成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

@Configuration 注解的 Full 模式和 Lite 模式!

開發(fā) 前端
如果設(shè)置了 proxyBeanMethods 屬性為 false,那么也就是 Lite 模式了,其實(shí)我們從屬性名稱上也能看出來端倪:是否代理 @Bean 注解標(biāo)記的方法。

@Configuration 注解相信各位小伙伴經(jīng)常會(huì)用到,但是大家知道嗎,這個(gè)注解有兩種不同的模式,一種叫做 Full 模式,另外一種則叫做 Lite 模式。

準(zhǔn)確來說,F(xiàn)ull 模式和 Lite 模式其實(shí) Spring 容器在處理 Bean 時(shí)的兩種不同行為。

這兩種不同的模式在使用時(shí)候的表現(xiàn)完全不同,今天松哥就來和各位小伙伴捋一捋這兩種模式。

1. 概念梳理

首先我們先來看一下 Spring 官方文檔中對(duì) Full 模式和 Lite 模式的一個(gè)介紹:

圖片圖片

截圖來自:https://docs.spring.io/spring-framework/reference/core/beans/java/basic-concepts.html

這個(gè)文檔主要講了這樣幾件事情:

  1. 我們可以通過在一個(gè)方法上添加 @Bean 注解,進(jìn)而將該方法的返回值暴露給 Spring 容器,在這種場(chǎng)景下,@Bean 注解實(shí)際上就是一種通用的工廠方法機(jī)制。
  2. 當(dāng)一個(gè)添加了 @Bean 注解的方法位于一個(gè)沒有添加 @Configuration 注解的類里邊時(shí),那么這個(gè)添加了 @Bean 注解的方法在處理時(shí)就會(huì)按照 Lite 模式來處理。
  3. 當(dāng)一個(gè) Bean 被聲明在添加了 @Component 注解的類中,那么會(huì)按照 Lite 模式來處理。
  4. 當(dāng)一個(gè) Bean 被聲明在一個(gè)普通的類中時(shí)(plain old class),按照 Lite 模式來處理(這一點(diǎn)感覺和第二點(diǎn)差不多)。
  5. 在 Lite 模式下,@Bean 注解標(biāo)記的方法最終不會(huì)被 CGLIB 進(jìn)行代理,就是一個(gè)普通的工廠方法,因此,在 @Bean 標(biāo)記的方法中,不能調(diào)用其他 @Bean 注解標(biāo)記的方法,如果有需要,可以通過方法參數(shù)注入自己所需要的 Bean。
  6. 由于 Lite 模式下并不會(huì)使用 CGLIB,因此 @Bean 標(biāo)記的方法可以是 final 類型的。
  7. 在大多數(shù)場(chǎng)景下,我們?cè)谝粋€(gè) @Configuration 注解標(biāo)記的類中,使用 @Bean 注解向 Spring 容器注冊(cè)一個(gè) Bean,都是 Full 模式。

官網(wǎng)文檔的介紹還是有些抽象,接下來松哥通過具體的案例來和大家演示 Full 模式和 Lite 模式的差別。

2. Full 模式

先看 Full 模式,中文也可以稱之為 完整 模式,我們平時(shí)使用時(shí),在一個(gè)配置類上添加 @Configuration 注解,且不添加任何額外屬性,這就是 Full 模式了。

Full 模式最大的特點(diǎn)是會(huì)給配置類通過 CGLIB 生成一個(gè)代理,所有被 @Bean 注解標(biāo)記的方法將來都是通過代理方法進(jìn)行調(diào)用。

假設(shè)我有如下配置類:

@Configuration
public class JavaConfig {

    @Bean
    User user() {
        return new User();
    }
}

現(xiàn)在,我們?nèi)?Spring 容器獲取這個(gè)配置類:

public class JavaDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(JavaConfig.class);
        JavaConfig config = ctx.getBean(JavaConfig.class);
        System.out.println("config.getClass() = " + config.getClass());
    }
}

打印結(jié)果如下:

圖片圖片

大家看到,最終從 Spring 容器中拿到的 JavaConfig 實(shí)例并不是原始的 JavaConfig 對(duì)象,而是一個(gè)被代理的 JavaConfig 對(duì)象。

為什么要代理呢?肯定是為了實(shí)現(xiàn)某些功能。

大家看下面這個(gè)案例:

@Configuration
public class JavaConfig {

    @Bean
    User user() {
        User user = new User();
        user.setDog(dog());
        return user;
    }
    
    @Bean
    Dog dog() {
        return new Dog();
    }
}

在 Full 模式下,在 user() 方法中調(diào)用 dog() 方法的時(shí)候,調(diào)用的是一個(gè)代理對(duì)象的 dog 方法,在這個(gè)代理對(duì)象的 dog 方法中,會(huì)首先去檢查 Spring 容器中是否存在 Dog 對(duì)象,如果存在,則直接使用 Spring 容器中的 dog 對(duì)象,就不會(huì)真正去執(zhí)行 dog 方法而獲取到一個(gè)新的 dog 對(duì)象了,如果 Spring 容器中不存在 dog 對(duì)象,才會(huì)創(chuàng)建新的 dog 對(duì)象出來。

一言以蔽之,在 Full 模式下,user 中的 dog 對(duì)象和 dog 方法注冊(cè)到 Spring 容器的 dog 對(duì)象是同一個(gè)。

在 Full 模式下,由于要給當(dāng)前類生成代理,然后去代理 @Bean 注解標(biāo)記的方法,因此,這些 @Bean 注解標(biāo)記的方法不能是 final 或者 private 類型的,因?yàn)?final 或者 private 類型的方法無法被重寫,也就沒法生成代理對(duì)象,如果添加了 final 或者 private 修飾符,那么會(huì)拋出如下異常:

圖片圖片

3. Lite 模式

再來看 Lite 模式,這種模式可以認(rèn)為是一種精簡(jiǎn)模式。

怎么開啟呢?我們可以去除配置類上的 @Configuration 注解,或者去除之后添加 @Component 注解,又或者使用 @ComponentScan、@ImportResource、@Import 等注解標(biāo)記類,那么最終都是 Lite 模式:

@Component
public class JavaConfig {

    @Bean
    final User user() {
        User user = new User();
        user.setDog(dog());
        return user;
    }

    @Bean
    Dog dog() {
        return new Dog();
    }
}

此時(shí)就是 Lite 模式,現(xiàn)在我們?nèi)?Spring 容器中獲取這個(gè)配置類:

public class JavaDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(JavaConfig.class);
        JavaConfig config = ctx.getBean(JavaConfig.class);
        System.out.println("config.getClass() = " + config.getClass());
    }
}

最終打印結(jié)果如下:

圖片圖片

大家看到,我們從 Spring 容器中拿到的就是原始的對(duì)象,而不是一個(gè)被代理過的對(duì)象。因此:

  1. 由于 @Bean 注解標(biāo)記的方法沒有被代理,因此,該方法可以是 final 也可以是 private,運(yùn)行時(shí)都不會(huì)報(bào)錯(cuò)。
  2. 由于 @Bean 方法沒有被代理,因此在 user 方法中調(diào)用 dog 方法的時(shí)候,就直接調(diào)用了,這就導(dǎo)致 user 中的 dog 和最終 dog 方法注冊(cè)到 Spring 容器中的 dog 不是同一個(gè)。

針對(duì)第二點(diǎn),如果想要確保 user 中的 dog 和 Spring 容器中的 dog 是同一個(gè),那么可以通過參數(shù)將所需要的對(duì)象注入進(jìn)來,類似下面這樣:

@Component
public class JavaConfig {

    @Bean
    final User user(Dog dog) {
        User user = new User();
        user.setDog(dog);
        return user;
    }

    @Bean
    Dog dog() {
        return new Dog();
    }
}

當(dāng) Spring 容器調(diào)用 user 方法初始化 User 對(duì)象時(shí),發(fā)現(xiàn)該方法還有參數(shù),因此會(huì)去容器中查找這個(gè)參數(shù),找到了直接使用。

另外,我們也可以在類上添加 @Configuration 注解,但是通過修改屬性值來啟用 Lite 模式:

@Configuration(proxyBeanMethods = false)
public class JavaConfig {

    @Bean
    final User user(Dog dog) {
        User user = new User();
        user.setDog(dog);
        return user;
    }

    @Bean
    Dog dog() {
        return new Dog();
    }
}

如果設(shè)置了 proxyBeanMethods 屬性為 false,那么也就是 Lite 模式了,其實(shí)我們從屬性名稱上也能看出來端倪:是否代理 @Bean 注解標(biāo)記的方法。

4. 小結(jié)

總結(jié)一下:

  1. Lite 模式下,配置類中的方法就是普通方法,可以是 final 類型,也可以是 private。
  2. Lite 模式下,不需要通過 CGLIB 生成動(dòng)態(tài)代理類,所以啟動(dòng)速度會(huì)快一些。
  3. Lite 模式下,一個(gè) @Bean 方法調(diào)用另外一個(gè) @Bean 方法,會(huì)導(dǎo)致同一個(gè) Bean 被初始化兩次。
  4. Full 模式下,會(huì)給配置類生成一個(gè)動(dòng)態(tài)代理類,配置類中的所有方法都將被動(dòng)態(tài)代理,因此配置類中的方法不能是 final 或者 private 的。
  5. Full 模式下,一個(gè) @Bean 方法調(diào)用另外一個(gè) @Bean 方法,動(dòng)態(tài)代理方法會(huì)先去容器中檢查是否存在該 Bean,如果存在,則直接使用容器中的 Bean,否則才會(huì)去創(chuàng)建新的對(duì)象。

日常開發(fā)中,我們使用較多的是 Full 模式。

責(zé)任編輯:武曉燕 來源: 江南一點(diǎn)雨
相關(guān)推薦

2023-05-23 22:06:47

云平臺(tái)

2010-09-27 15:17:48

JVM client模式server模式

2011-08-01 10:35:26

數(shù)據(jù)庫外模式模式

2023-10-25 08:17:06

Lite模式代理類

2021-04-19 21:25:48

設(shè)計(jì)模式到元

2024-04-12 12:10:18

Python設(shè)計(jì)模式開發(fā)

2023-10-30 18:59:38

REST API開發(fā)

2022-04-15 08:30:00

Lombok@Builde構(gòu)建器

2010-09-27 16:07:06

JVM Server模Client模式

2024-06-04 13:11:52

Python行為設(shè)計(jì)模式開發(fā)

2012-02-10 09:55:26

2012-08-30 09:07:33

設(shè)計(jì)模式

2015-10-22 13:10:43

CDN

2010-10-28 11:36:16

Oracle用戶

2022-10-27 11:46:48

ConfiguratValuespring

2022-08-29 15:26:58

MySQLSQL模式

2021-03-06 22:50:58

設(shè)計(jì)模式抽象

2025-01-09 11:15:47

2009-12-28 10:47:17

MPLS技術(shù)

2013-11-08 14:57:37

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 久久综合久色欧美综合狠狠 | 欧美阿v | 成人1区2区 | 欧美一级在线免费 | 精品视频一区二区在线观看 | 日韩一区二区福利 | 搞黄视频免费看 | 羞羞涩涩在线观看 | 亚洲最大的成人网 | 成人一区二区视频 | 亚洲在线观看视频 | 久久国际精品 | 91大片 | 一区二区小视频 | 国产乱码精品一品二品 | 欧产日产国产精品视频 | 欧美亚洲视频 | 日本不卡免费新一二三区 | 亚洲精品久久久 | 日韩视频精品 | 黄色成人免费在线观看 | 国产精品一区二区三区在线 | 一级黄色播放 | 97av视频在线观看 | 日韩精品一区中文字幕 | 中文字幕四虎 | 久久这里只有精品首页 | 日韩二区三区 | 中文字幕视频在线免费 | 一区二区三区中文 | 黄色一级视频免费 | www.国产.com| 欧美一级久久久猛烈a大片 日韩av免费在线观看 | 亚洲不卡在线观看 | 久久精品亚洲精品国产欧美 | 亚洲精品乱码久久久久久久久久 | 国产一级片免费视频 | 成人二区 | 亚洲欧美在线一区 | 国内精品久久影院 | 91中文字幕在线 |