錦州網(wǎng)站建設(shè)哪家好seo策略有哪些
@Bean 標(biāo)注的方法如何創(chuàng)建對(duì)象呢?
參考文章:https://blog.csdn.net/qq_35971258/article/details/128241353
下邊只講一下 @Bean 注解標(biāo)注的方法,是如何去進(jìn)行創(chuàng)建 bean,以及流程是怎樣的,如果需要看源碼具體執(zhí)行流程,可以查看上邊
參考文章
Spring 的 @Bean 標(biāo)注的方法會(huì)被創(chuàng)建成 Bean,這個(gè)創(chuàng)建的過(guò)程在源碼中是怎么執(zhí)行的呢?
@Configuration
public class MyConfiguration {@Beanpublic Blue blue() {System.out.println("創(chuàng)建 Blue 對(duì)象");return new Blue();}}
當(dāng)使用上述代碼時(shí),在 Spring 中掃描到 MyConfiguration 類(lèi)時(shí),會(huì)發(fā)現(xiàn) MyConfiguration 的 BeanDefinition 包含了 FactoryMethod,也就是 Spring 為帶有 @Bean 注解的方法創(chuàng)建了一個(gè) FactoryMethod,這個(gè) FactoryMethod 也就是 blue()
方法,最后通過(guò)執(zhí)行 FactoryMethodblue()
就可以創(chuàng)建出 Blue 對(duì)象,再將 Blue 對(duì)象交給 Spring 進(jìn)行管理,最后創(chuàng)建的 Blue 對(duì)象的 beanName 就是 @Bean 標(biāo)注的方法名
總結(jié)一下:@Bean 標(biāo)注的方法會(huì)是一個(gè) FactoryMethod,最后通過(guò)執(zhí)行這個(gè) FactoryMethod 來(lái)創(chuàng)建 Bean 對(duì)象,beanName 為方法名 {beanName: blud, }
Spring 的 @Bean 標(biāo)注的方法的參數(shù)如何注入的呢?
@Configuration
public class MyConfiguration {@Beanpublic Blue blue(White white) {System.out.println("創(chuàng)建 Blue 對(duì)象");System.out.println("獲取了 White 對(duì)象:" + white);return new Blue();}@Beanpublic White white() {White white = new White();System.out.println("創(chuàng)建的 White 對(duì)象:" + white);return white;}/*** 輸出:* 創(chuàng)建的 White 對(duì)象:com.zqy.springbean.SpringBean.beans.White@32c726ee* 創(chuàng)建 Blue 對(duì)象* 獲取了 White 對(duì)象:com.zqy.springbean.SpringBean.beans.White@32c726ee*/
}
參數(shù)注入流程為:
- 對(duì)上邊的 @Bean 方法來(lái)說(shuō),如果方法存在參數(shù),會(huì)先根據(jù)參數(shù)名到 Spring 容器中取出對(duì)應(yīng)的 bean,即先根據(jù)
white
取出對(duì)應(yīng)的 bean - 如果根據(jù)
white
沒(méi)有取到對(duì)應(yīng)的 bean,就會(huì)根據(jù)對(duì)象的類(lèi)型去取,如果 Spring 容器中,White
類(lèi)型的 Bean 只有 1 個(gè),就會(huì)取出來(lái)進(jìn)行賦值 - 但是如果 Spring 容器中
White
類(lèi)型的 Bean 有多個(gè)時(shí),Spring 內(nèi)部就會(huì)進(jìn)行決策判斷,通過(guò)決策判斷出來(lái)需要使用哪個(gè) Bean 進(jìn)行賦值,如果沒(méi)有決策成功,Spring 就會(huì)報(bào)錯(cuò)Parameter 0 of method blue in com.zqy.springbean.SpringBean.MyConfiguration required a single bean, but 2 were found:
,即 Spring 根據(jù)類(lèi)型找到了多個(gè) Bean,但是并不知道使用哪一個(gè)!
這個(gè)決策過(guò)程為:
- 如果 Spring 找到多個(gè)同類(lèi)型的 Bean,會(huì)查看是否有 Bean 標(biāo)注了 @Primary 注解,如果有,就使用該 Bean 進(jìn)行賦值
- 如果沒(méi)有標(biāo)注 @Primary,則會(huì)判斷這幾個(gè) Bean 是否實(shí)現(xiàn)了 @Comparator 排序接口,如果有,就使用該 Bean
- 如果都沒(méi)有找到,再根據(jù)入?yún)⒚Q(chēng)和 beanName 進(jìn)行比較,如果相同就使用該 Bean,否則報(bào)錯(cuò)
下面我們對(duì)這幾種情況進(jìn)行代碼演示:
-
根據(jù) beanName 找到入?yún)?/p>
會(huì)發(fā)現(xiàn)根據(jù) beanName 成功找到 bean 對(duì)象,賦值給 blue() 方法的入?yún)?/p>
@Configuration public class MyConfiguration {@Beanpublic Blue blue(White white1) {System.out.println("獲取了 White 對(duì)象:" + white1);return new Blue();}@Beanpublic White white1() {White white = new White();System.out.println("創(chuàng)建的 White1 對(duì)象:" + white);return white;}/*** 輸出:創(chuàng)建的 White1 對(duì)象:com.zqy.springbean.SpringBean.beans.White@2c07545f獲取了 White 對(duì)象:com.zqy.springbean.SpringBean.beans.White@2c07545f*/ }
-
如果有多個(gè)同類(lèi)型的 bean,根據(jù) @Primary 找到 Bean 進(jìn)行賦值
可以發(fā)現(xiàn),入?yún)⒆⑷氲?bean 對(duì)象為攜帶了 @Primary 注解的 bean
@Configuration public class MyConfiguration {@Beanpublic Blue blue(White white) {System.out.println("獲取了 White 對(duì)象:" + white);return new Blue();}@Bean@Primarypublic White white1() {White white = new White();System.out.println("創(chuàng)建的 White1 對(duì)象,攜帶 @Primary 注解:" + white);return white;}@Beanpublic White white2() {White white = new White();System.out.println("創(chuàng)建的 White2 對(duì)象:" + white);return white;}/*** 輸出:創(chuàng)建的 White1 對(duì)象,攜帶 @Primary 注解:com.zqy.springbean.SpringBean.beans.White@2c4d1ac獲取了 White 對(duì)象:com.zqy.springbean.SpringBean.beans.White@2c4d1ac創(chuàng)建的 White2 對(duì)象:com.zqy.springbean.SpringBean.beans.White@7f0d96f2*/ }
-
有多個(gè)同類(lèi)型的 bean,根據(jù)
入?yún)⒚?/code>和
beanName
比較進(jìn)行賦值可以發(fā)現(xiàn),入?yún)⒚麨?
white1
,White 類(lèi)型的 bean 有兩個(gè),beanName 分別為white1
和white2
,根據(jù)比較,入?yún)⑹褂?white1
的 bean@Configuration public class MyConfiguration {@Beanpublic Blue blue(White white1) {System.out.println("獲取了 White 對(duì)象:" + white1);return new Blue();}@Beanpublic White white1() {White white = new White();System.out.println("創(chuàng)建的 White1 對(duì)象:" + white);return white;}@Beanpublic White white2() {White white = new White();System.out.println("創(chuàng)建的 White2 對(duì)象:" + white);return white;}/*** 輸出:創(chuàng)建的 White1 對(duì)象:com.zqy.springbean.SpringBean.beans.White@2c07545f獲取了 White 對(duì)象:com.zqy.springbean.SpringBean.beans.White@2c07545f創(chuàng)建的 White2 對(duì)象:com.zqy.springbean.SpringBean.beans.White@e57b96d*/ }
?