SpringBoot配置@Configuration注解和@bean注解
1.@Configuration注解
用法:作用在類上面 作用:告訴SpringBoot這是一個配置類,相當于Spring中的xml配置文件。
@Configuration //告訴SpringBoot這是一個配置類 == 配置文件
public class Config {
}2.@bean注解
用法:配置類里面使用@Bean標注在方法上給IoC容器注冊組件,默認也是單實例的 作用:給容器中添加組件,相當于Spring中xml配置文件中的<bean>標簽。 理解:以方法名作為組件的id。返回類型就是組件類型。返回的值,就是組件在容器中的實例
@Configuration //告訴SpringBoot這是一個配置類 == 配置文件
public class Config {
@Bean //給容器中添加組件。以方法名作為組件的id。返回類型就是組件類型。返回的值,就是組件在容器中的實例
public Person person1(){
return new Person("Mr.Yu",21,"male");
}
@Bean("customize") //id值也可以指定
public Person person2(){
return new Person("小明",20,"male");
}
}在主程序類中打印輸出我們IoC容器中的對象,看看我們的person1和customize有沒有添加到容器中
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
//1.返回我們IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
//2.查看容器里面的組件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
}輸出結果:

可以看到輸出結果中有我們存放進IoC容器的兩個對象
3.單實例
@Bean注解存入到IoC容器中的實例也是單實例的
public static void main(String[] args) {
//1.返回我們IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
//2.查看容器里面的組件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
//單實例
Person person1 = run.getBean("person1",Person.class);
Person person2 = run.getBean("person1",Person.class);
System.out.println("person1 == person2 :"+ (person1 == person2));
}輸出結果:

4.配置類也是容器的組件
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
//1.返回我們IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
//2.查看容器里面的組件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
//配置類本身也是組件
Config bean = run.getBean(Config.class);
//com.ysw.boot.config.Config$$EnhancerBySpringCGLIB$$4aa44992@381d7219
System.out.println(bean);
}
}輸出結果:
com.ysw.boot.config.Config$$EnhancerBySpringCGLIB$$4aa44992@381d7219
5.直接調(diào)用配置類里面的person1()方法
如果我們直接調(diào)用配置類里面的person1()方法會發(fā)生什么情況,它是從IoC容器中拿還是直接new一個對象呢
- 在new一個配置類出來的情況下,調(diào)用person1方法,它返回的是new出來的對象
- 但是如果我們從容器中取得的配置類,無論再去掉用多少次person1方法,它始終返回的都是同一個單實例對象,也就是從IoC容器中拿的對象。
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
//1.返回我們IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
//2.查看容器里面的組件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
//配置類本身也是組件
Config bean = run.getBean(Config.class);
//獲取到的本身就是代理對象
//com.ysw.boot.config.Config$$EnhancerBySpringCGLIB$$4aa44992@381d7219
System.out.println(bean);
//如果我們直接調(diào)用person1方法,它是從IoC容器中拿還是直接new一個對象呢,
//在new一個配置類出來的情況下,調(diào)用person1方法,它返回的是new出來的對象
Config config = new Config();
Person person3 = config.person1();
Person person4 = config.person1();
System.out.println("person3 == person4 :"+ (person3 == person4));
//但是如果我們從容器中取得的配置類,無論再去掉用多少次person1方法,它始終返回的都是同一個單實例對象,也就是從IoC容器中拿的對象。
//如果@Configuration(proxyBeanMethods = true)代理對象調(diào)用方法。SpringBoot總會檢查這個組件是否在容器中有;
//保持組件單實例
Person person5 = bean.person1();
Person person6 = bean.person1();
System.out.println("person5 == person6 :"+ (person5 == person6));
}
}輸出結果:

6.proxyBeanMethods——代理bean的方法
從容器中獲取到的配置類對象輸出結果:
com.ysw.boot.config.Config$$EnhancerBySpringCGLIB$$4aa44992@381d7219
在上述的輸出結果中我們可以看到從容器中獲取到的配置類對象本身就是一個被SpringCGLIB增強了的代理對象
@Configuration()默認設置的是proxyBeanMethods = true。- 如果
@Configuration(proxyBeanMethods = true),就是代理對象調(diào)用方法。SpringBoot總會檢查這個組件是否在容器中已有,調(diào)用配置類中的方法時會返回容器中已有的組件(即IoC容器中已存在的對象)。 - 如果
@Configuration(proxyBeanMethods = false),就不是代理對象調(diào)用方法,SpringBoot不會檢查這個組件是否在容器中已有,調(diào)用配置類中的方法時會返回新對象。
@Configuration(proxyBeanMethods = false)
舉例: 把上述5中的@Configuration()改為@Configuration(proxyBeanMethods = false)
輸出結果為:

總結:
- Full模式(proxyBeanMethods = true):保證每個@Bean方法被調(diào)用多少次返回的組件都是單實例的
- Lite模式(proxyBeanMethods = false):每個@Bean方法被調(diào)用多少次返回的組件都是新創(chuàng)建的
- 組件依賴必須使用Full模式默認。其他默認是否Lite模式
- 配置類組件之間無依賴關系用Lite模式加速容器啟動過程,調(diào)用配置類中的方法時,SpringBoot每次都不會判斷對象在容器中是否已經(jīng)存在,減少了判斷過程
- 配置類組件之間有依賴關系,調(diào)用配置類中的方法時,SpringBoot每次都會判斷對象在容器中是否已經(jīng)存在,方法會被調(diào)用得到之前單實例組件,用Full模式
到此這篇關于SpringBoot配置@Configuration注解和@bean注解的文章就介紹到這了,更多相關SpringBoot配置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringCloud中Sentinel基礎場景和異常處理方式
這篇文章主要介紹了SpringCloud中Sentinel基礎場景和異常處理方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-04-04
mybatis教程之動態(tài)sql語句_動力節(jié)點Java學院整理
這篇文章主要介紹了mybatis教程之動態(tài)sql語句,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09
mybatis報錯?resultMapException的解決
這篇文章主要介紹了mybatis報錯?resultMapException的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01

