SpringBoot?@Configuration與@Bean注解使用介紹
之前我們都是通過xml的方式定義bean,里面會寫很多bean元素,然后spring啟動的時候,就會讀取bean xml配置文件,然后解析這些配置,然后會將這些bean注冊到spring容器中,供使用者使用。
Spring3.0開始,@Configuration用于定義配置類,定義的配置類可以替換xml文件,一般和@Bean注解聯(lián)合使用。
@Configuration注解可以加在類上,讓這個類的功能等同于一個bean xml配置文件。
@Bean注解類似于bean xml配置文件中的bean元素,用來在spring容器中注冊一個bean。
demo示例
1.創(chuàng)建一個工程
2.創(chuàng)建bean文件夾并創(chuàng)建兩個示例用戶和部門
如下:
用戶
package com.example.ethan.bean;
public class User {
private String name;
private Integer age;
private Dept dept;
public User() {
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}部門
package com.example.ethan.bean;
public class Dept {
private String name;
public Dept(String name) {
this.name = name;
}
}3.創(chuàng)建配置類
使用@Configuration注解,并使用@Bean注解創(chuàng)建bean
package com.example.ethan.config;
import com.example.ethan.bean.Dept;
import com.example.ethan.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration //告訴SpringBoot這是一個配置類 == 配置文件
public class ConfigDemo {
@Bean //給容器中添加組件。以方法名作為組件的id。返回類型就是組件類型。返回的值,就是組件在容器中的實例
public User user01(){
User zhangsan = new User("zhangsan", 18);
return zhangsan;
}
@Bean("my rd")
public Dept rd(){
return new Dept("研發(fā)部");
}
}4.在主程序查看
編寫主程序,查看容器中的Bean
package com.example.ethan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class EthanApplication {
public static void main(String[] args) {
// 返回ioc容器
ConfigurableApplicationContext run = SpringApplication.run(EthanApplication.class, args);
// 查看容器組件
String[] beanDefinitionNames = run.getBeanDefinitionNames();
System.out.println("========================");
for (String name : beanDefinitionNames) {
System.out.println(name);
}
}
}運行后可以看到configDemo、user01、my rd都已經(jīng)被容器管理。
特點和特性
1.配置類本身也是組件,也會有被IOC容器管理的Bean,且是一個單實例的代理對象。
在主程序驗證代碼如下:
ConfigDemo bean = run.getBean(ConfigDemo.class); System.out.println(bean);
// 結(jié)果:com.example.ethan.config.ConfigDemo$$EnhancerBySpringCGLIB$$24eef7b3@a619c2
可以看到得到的bean是一個CGLIB代理對象。
2.默認(rèn)被IOC容器管理@Bean注解產(chǎn)生的Bean是單實例的。
在主程序驗證代碼如下:
Dept d1 = run.getBean("my rd", Dept.class);
Dept d2 = run.getBean("my rd", Dept.class);
System.out.println("組件:"+(d1 == d2));
// 組件:true
結(jié)果為true,證明@Bean注解產(chǎn)生的Bean是單實例的。
3.@configration的proxyBeanMethods屬性。
這個屬性默認(rèn)為true。他的意思就是,當(dāng)從容器獲取Bean時,是否用上面第1點中的代理對象調(diào)用方法獲取bean。
增加驗證如下:
ConfigDemo bean = run.getBean(ConfigDemo.class);
System.out.println(bean);
// 如果@Configuration(proxyBeanMethods = true)代理對象調(diào)用方法
User user = bean.user01();
User user1 = bean.user01();
System.out.println(user == user1);當(dāng)configration的proxyBeanMethods=true時,結(jié)果為true,否則結(jié)果為false。
也就是,當(dāng)proxyBeanMethods=true,使用代理對象獲取Bean,代理會攔截所有被@Bean修飾的方法,默認(rèn)情況(bean為單例)下確保這些方法只被調(diào)用一次,放進(jìn)容器,然后從容器查找到,就會直接使用,從而確保這些bean是同一個bean,即單例的。
否則,不使用代理對象獲取Bean,每次獲取都新建,所以兩個Bean不相等。
這樣做的主要目的是為了解決組件依賴問題,比如下面的部門被用戶
依賴,可以保證用戶依賴的部門是單實例。
驗證代碼如下:
首先讓用戶依賴部門
package com.example.ethan.config;
import com.example.ethan.bean.Dept;
import com.example.ethan.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods=true) //告訴SpringBoot這是一個配置類 == 配置文件
public class ConfigDemo {
@Bean //給容器中添加組件。以方法名作為組件的id。返回類型就是組件類型。返回的值,就是組件在容器中的實例
public User user01(){
User zhangsan = new User("zhangsan", 18);
//user組件依賴了Dept組件
zhangsan.setDept(rd());
return zhangsan;
}
@Bean("my rd")
public Dept rd(){
return new Dept("研發(fā)部");
}
}然后測試用戶依賴的組件是否是容器中的Bean
User user01 = run.getBean("user01", User.class);
Dept dept = run.getBean("tom", Dept.class);
System.out.println("用戶的寵物:"+(user01.getDept() == dept));
// // 用戶的部門:true
測試可以看到,當(dāng)proxyBeanMethods=true時,結(jié)果為true,否則為false。
當(dāng)proxyBeanMethods=true時也稱為 Full模式,否則稱為Lite模式。
Full(proxyBeanMethods = true)【保證每個@Bean方法被調(diào)用多少次返回的組件都是單實例的】
Lite(proxyBeanMethods = false)【每個@Bean方法被調(diào)用多少次返回的組件都是新創(chuàng)建的】
組件依賴必須使用Full模式默認(rèn)。其他默認(rèn)是否Lite模式。
最佳實戰(zhàn)
- 配置 類組件之間無依賴關(guān)系用Lite模式加速容器啟動過程,減少判斷
- 配置類組件之間有依賴關(guān)系,方法會被調(diào)用得到之前單實例組件,用Full模式
到此這篇關(guān)于SpringBoot @Configuration與@Bean注解使用介紹的文章就介紹到這了,更多相關(guān)SpringBoot @Configuration與@Bean內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring項目中使用Junit單元測試并配置數(shù)據(jù)源的操作
這篇文章主要介紹了Spring項目中使用Junit單元測試并配置數(shù)據(jù)源的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
Spring6當(dāng)中獲取Bean的四種方式小結(jié)
Spring 為Bean 的獲取提供了多種方式,通常包括4種方式,(也就是說在Spring中為Bean對象的創(chuàng)建準(zhǔn)備了多種方案,目的是:更加靈活),本文將通過代碼示例詳細(xì)的給大家介紹了一下這四種方式,需要的朋友可以參考下2024-04-04
Spring Boot接收單個String入?yún)⒌慕鉀Q方法
這篇文章主要給大家介紹了關(guān)于Spring Boot接收單個String入?yún)⒌慕鉀Q方法,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11
IDEA里找不到Maven的有效解決辦法(小白超詳細(xì))
這篇文章主要給大家介紹了關(guān)于IDEA里找不到Maven的有效解決辦法,文中通過圖文將解決的辦法介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-07-07

