SpringBoot2底層注解@Configuration配置類詳解
SpringBoot2底層注解@Configuration配置類
一、配置類
@Configuration這個注解作用就是告訴 springboot 這是一個配置類。
這個配置已經不陌生了,在之前 spring 相關的使用全注解方式時,就使用到了配置類。
在配置類里,可以使用@Bean標記在方法上,給容器注冊組件,默認也是單實例的。
@Configuration //告訴SpringBoot這是一個配置類 == 配置文件
public class MyConfig {
@Bean("user1") //給容器中添加組件。以方法名作為組件的id。返回類型就是組件類型。返回的值,就是組件在容器中的實例
public User user01(){
return new User("pingguo", 20);
}
@Bean("pet1")
public Pet tomcatPet(){
return new Pet("tomcat");
}
}主運行類還是之前示例中的,打印出所有組件的名稱。

可以看到,有上面注冊的 2 個組件:user1、pet1。
二、配置類本身也是組件
在主運行類的 main 方法里,加一個獲取配置類的輸出:
@SpringBootApplication(scanBasePackages = "com.pingguo")
public class MainApplication {
public static void main(String[] args) {
// 返回IOC容器
final ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
// 查看容器里的組件
final String[] beanDefinitionNames = run.getBeanDefinitionNames();
for (String name: beanDefinitionNames) {
System.out.println(name);
}
// 從容器中獲取組件
MyConfig bean = run.getBean(MyConfig.class);
System.out.println("配置類也是組件:" + bean);
}
}運行 main 方法,

可以看到最后一個輸出,說明配置類本身也是個組件。
三、proxyBeanMethods 屬性
從springboot2.0之后,@Configuration 中多了一個屬性 proxyBeanMethods,用來代理 bean 的。
默認值是true,也就是說該配置類會被代理(CGLIB),在同一個配置文件中調用其它被@Bean注解標注的方法獲取對象時,springboot 總會檢查容器中是否存在這個組件。
如果容器中存在,直接取。不存在的話,才會去創(chuàng)建,保證單實例。
現在看下false的情況。
@Configuration(proxyBeanMethods = false) //改成 false
public class MyConfig {
@Bean("user1") //給容器中添加組件。以方法名作為組件的id。返回類型就是組件類型。返回的值,就是組件在容器中的實例
public User user01(){
return new User("pingguo", 20);
}
@Bean("pet1")
public Pet tomcatPet(){
return new Pet("tomcat");
}
}在主運行程序里多從調用方法獲取對象,判斷一下對象是否相等。
@SpringBootApplication(scanBasePackages = "com.pingguo")
public class MainApplication {
public static void main(String[] args) {
// 返回IOC容器
final ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
// 查看容器里的組件
final String[] beanDefinitionNames = run.getBeanDefinitionNames();
for (String name: beanDefinitionNames) {
System.out.println(name);
}
// 從容器中獲取組件
MyConfig bean = run.getBean(MyConfig.class);
System.out.println("配置類也是組件:" + bean);
User user1 = bean.user01();
User user2 = bean.user01();
System.out.println(user1 == user2);
}
}看最后的輸出,會是 false。

這里引出 2 個名詞:Full 全模式,Lite 輕量級模式。
- Full (proxyBeanMethods = true) : 該模式下注入容器中的同一個組件無論被取出多少次都是同一個bean實例,即單實例對象,
- 在該模式下 SpringBoot 每次啟動都會判斷檢查容器中是否存在該組件。
- Lite (proxyBeanMethods = false): 該模式下注入容器中的同一個組件無論被取出多少次都是不同的bean實例,即多實例對象,
在該模式下 SpringBoot 每次啟動會跳過檢查容器中是否存在該組件。
那么這個是用來解決什么場景的問題呢?答案:組件依賴。
有組件依賴的場景
看下2個實體類:User、Pet。
public class User {
private String name;
private Integer age;
private Pet pet;
... ...固定代碼部分:有參構造、無參構造、get和set方法、toString方法,就省去了。
public class Pet {
private String name;
... ...修改下配置類里的方法:
@Configuration(proxyBeanMethods = true)
public class MyConfig {
@Bean("user1")
public User user01(){
User pingguo = new User("pingguo",20);
pingguo.setPet(tomcatPet());
return pingguo;
}
@Bean("pet1")
public Pet tomcatPet(){
return new Pet("tomcat");
}
}到main方法測試一下:
// 依賴關系
User user01 = run.getBean("user1", User.class);
Pet pet1 = run.getBean("pet1", Pet.class);
System.out.println("依賴:" + (user01.getPet() == pet1));這里就是判斷當proxyBeanMethods = true的情況下,User對象的 pet,是不是容器中的 pet。
如果是,那么結果就是true。

此時再將proxyBeanMethods = false,重新運行一下,結果會是 false:

那么這 2 個模式分別在什么時候用呢?
當在你的同一個Configuration配置類中,注入到容器中的 bean 實例之間有依賴關系時,建議使用 Full 全模式。
當在你的同一個Configuration配置類中,注入到容器中的 bean 實例之間沒有依賴關系時,建議使用 Lite 輕量級模式,以提高 springboot 的啟動速度和性能。
以上就是SpringBoot2底層注解@Configuration配置類詳解的詳細內容,更多關于SpringBoot2注解@Configuration的資料請關注腳本之家其它相關文章!
相關文章
Java8 使用工廠方法supplyAsync創(chuàng)建CompletableFuture實例
這篇文章主要介紹了Java8 使用工廠方法supplyAsync創(chuàng)建CompletableFuture實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
Java中ArrayList去除重復元素(包括字符串和自定義對象)
本文主要介紹了Java中ArrayList去除重復元素(包括字符串和自定義對象)的方法。具有很好的參考價值。下面跟著小編一起來看下吧2017-03-03

