Spring注解中@Configuration和@Component到底有啥區(qū)別
Spring 注解中 @Configuration 和 @Component 的區(qū)別總結(jié)為一句話就是:
@Configuration 中所有帶 @Bean 注解的方法都會(huì)被動(dòng)態(tài)代理(cglib),因此調(diào)用該方法返回的都是同一個(gè)實(shí)例。而 @Conponent 修飾的類不會(huì)被代理,每實(shí)例化一次就會(huì)創(chuàng)建一個(gè)新的對(duì)象。
在 @Configuration 注解的源代碼中,使用了 @Component 注解:
從定義來看, @Configuration
注解本質(zhì)上還是 @Component
,因此 <context:component-scan/>
或者 @ComponentScan
都能處理 @Configuration
注解的類。
下面我們通過一個(gè)例子來說明上述情況:
// 使用@Configuration和@Bean注解創(chuàng)建Room實(shí)例和People實(shí)例,并注入進(jìn)spring容器 @Configuration public class RoomPeopleConfig { @Bean public Room room() { Room room = new Room(); room.setId(1); room.setName("房間"); room.setPeople(people());// 在創(chuàng)建Room實(shí)例時(shí),再調(diào)用一次People()創(chuàng)建一個(gè)People實(shí)例 return room; } @Bean public People people() { People people = new People(); people.setId(1); people.setName("小明"); return people; } } // 下面是測(cè)試代碼 @SpringBootTest @ContextConfiguration(classes = Application.class) public class ConfigurationTests { @Autowired private Room room; @Autowired private People people; @Test public void test() { System.out.println(people == room.getPeople() ? "是同一個(gè)實(shí)例" : "不是同一個(gè)實(shí)例"); } }
輸出結(jié)果:
如果將 @Configuration 換成 @Component ,則輸出:
從上面的結(jié)果可以發(fā)現(xiàn)使用 @Configuration 時(shí)在 people 和 spring 容器之中的是同一個(gè)對(duì)象,而使用 @Component 時(shí)是不同的對(duì)象。這就是因?yàn)?@Configuration 使用了 cglib 動(dòng)態(tài)代理,返回的是同一個(gè)實(shí)例對(duì)象。
雖然 @Component 注解也會(huì)當(dāng)做配置類,但是并不會(huì)為其生成 CGLIB 代理 Class,所以在生成 room 對(duì)象時(shí)和生成 people 對(duì)象時(shí)調(diào)用 people( ) 方法執(zhí)行了兩次 new 操作,所以是不同的對(duì)象。當(dāng)使用 @Configuration 注解時(shí),生成當(dāng)前對(duì)象的子類 Class,并對(duì)方法攔截,第二次調(diào)用 people()方法時(shí)直接從 BeanFactory 之中獲取對(duì)象,所以得到的是同一個(gè)對(duì)象。
其具體底層的實(shí)現(xiàn)原理可以去看一看這篇文章:configuration和component區(qū)別底層實(shí)現(xiàn)
總結(jié)
到此這篇關(guān)于Spring注解中@Configuration和@Component到底有啥區(qū)別的文章就介紹到這了,更多相關(guān)@Configuration和@Component的區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
rabbitmq五種模式詳解(含實(shí)現(xiàn)代碼)
這篇文章主要介紹了rabbitmq五種模式詳解(含實(shí)現(xiàn)代碼),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04Spring Boot使用Redisson實(shí)現(xiàn)滑動(dòng)窗口限流的項(xiàng)目實(shí)踐
滑動(dòng)窗口限流是一種流量控制策略,用于控制在一定時(shí)間內(nèi)的請(qǐng)求頻率,本文主要介紹了Spring Boot使用Redisson實(shí)現(xiàn)滑動(dòng)窗口限流的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03java操作mongodb之多表聯(lián)查的實(shí)現(xiàn)($lookup)
這篇文章主要介紹了java操作mongodb之多表聯(lián)查的實(shí)現(xiàn)($lookup),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03詳解spring cloud構(gòu)建微服務(wù)架構(gòu)的網(wǎng)關(guān)(API GateWay)
這篇文章主要介紹了詳解spring cloud構(gòu)建微服務(wù)架構(gòu)的網(wǎng)關(guān)(API GateWay),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01手動(dòng)編譯并運(yùn)行Java項(xiàng)目實(shí)現(xiàn)過程解析
這篇文章主要介紹了手動(dòng)編譯并運(yùn)行Java項(xiàng)目實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10Java編程實(shí)現(xiàn)比對(duì)兩個(gè)文本文件并標(biāo)記相同與不同之處的方法
這篇文章主要介紹了Java編程實(shí)現(xiàn)比對(duì)兩個(gè)文本文件并標(biāo)記相同與不同之處的方法,涉及java針對(duì)文本文件的讀取、遍歷、判斷等相關(guān)操作技巧,需要的朋友可以參考下2017-10-10SpringBoot+JUnit5+MockMvc+Mockito單元測(cè)試的實(shí)現(xiàn)
今天聊聊如何在 SpringBoot 中集成 Junit5、MockMvc、Mocktio。Junit5 是在 Java 棧中應(yīng)用最廣的測(cè)試框架,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09