關于@Configuration的作用說明
一、問題描述
在項目中,通常都會配置一個或者多個加了@Configuration注解的配置類,那么@Configuration這個注解到底有神馬作用勒?
@ComponentScan("com")
public class AppConfig {
?? ?@Bean
?? ?public TestDao testDao() {
?? ??? ?return new TestDao();
?? ?}
}public class Test {
?? ?public static void main(String[] args) {
?? ??? ?AnnotationConfigApplicationContext acc = new AnnotationConfigApplicationContext(AppConfig.class);
?? ?}
}public class TestDao {
?? ?public TestDao(){
?? ??? ?System.out.println("testDao");
?? ?}
}執(zhí)行上面的代碼,我們會發(fā)現(xiàn)當我們不加@Configuration這個注解的時候我們的TestDao 這個類還是還是會被實例化,也會打印testDao。我們的spring環(huán)境也可以正常運行。

那么我們的@Configuration注解是來解決什么問題的勒?
我們來看一下下面這段代碼。當我們在AppConfig中有2個方法,而且第二個方法調用了第一個方法。
@ComponentScan("com")
public class AppConfig {
@Bean
public TestDao testDao() {
return new TestDao();
}
@Bean
public TestDao1 testDao1() {
testDao();
return new TestDao1();
}
}
public class TestDao1 {
public TestDao1(){
System.out.println("testDao1");
}
}
不加@Configuration的打印結果:

加上@Configuration的打印結果:

二、分析
從表面來看,當我們不加@Configuration注解的時候,我們的TestDao會被實例化兩次,這違背了我們spring默認單例的設計原則,當加上我們的@Configuration注解的時候,TestDao只被實例化了一次。
那么其底層到底做了什么,讓我們來深追一下spring源碼吧。
當我們解析beanAppcofig的時候,會給它的一個屬性標識為Full,表明它是一個全注解類。


然后在我們調用ConfigurationClassPostProcessor.postProcessBeanFactory()方法的時候會去判斷我們的bean工廠當中是否有bean需要進行cglib代理。


然后遍歷configBeanDefs這個map



cglib代理主要是對我們的方法進行攔截增強;當我們執(zhí)行AppConfig中的方法的時候會去執(zhí)行cglib代理類中的代理方法,主要就是callBacks中的方法。



isCurrentlyInvokedFactoryMethod(beanMethod))
會判斷我們的執(zhí)行方法和我們的調用方法是否是同一個;如果是同一個就調用父類的方法進行new;如果不是就調用$$beanFactory.getBean()獲取。

三、總結
加上@Configuration注解主要是給我們的類加上了cglib代理。
在執(zhí)行我們的配置類的方法時,會執(zhí)行cglib代理類中的方法,其中有一個非常重要的判斷,當我們的執(zhí)行方法和我們的調用方法是同一個方法時,會執(zhí)行父類的方法new(cglib代理基于繼承);當執(zhí)行方法和調用方法不是同一個方法時會調用beanFactory.getBean獲取。


相關文章
Java源碼解析HashMap的tableSizeFor函數(shù)
今天小編就為大家分享一篇關于Java源碼解析HashMap的tableSizeFor函數(shù),小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-01-01
WebSocket實現(xiàn)數(shù)據(jù)庫更新時前端頁面刷新
這篇文章主要為大家詳細介紹了WebSocket實現(xiàn)數(shù)據(jù)庫更新時前端頁面刷新,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-04-04
SpringCloud服務實現(xiàn)同時使用eureka和nacos方法
這篇文章主要介紹了SpringCloud服務實現(xiàn)同時使用eureka和nacos方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2023-01-01

