1. 程式人生 > >Spring @Configuration 和 @Component 區別(精簡彙總版)

Spring @Configuration 和 @Component 區別(精簡彙總版)

 

Spring @Configuration 和 @Component 區別

內部原理其實也是挺複雜的,用最簡單的語言彙總以下兩者的區別,只要理解的就ok了,深入瞭解的話可以繼續搜尋下其他的文件。

彙總版本

@Configuration 中所有帶 @Bean 註解的方法都會被動態代理,因此呼叫該方法返回的都是同一個例項。

 

@Configuration 註解本質上還是 @Component,因此 <context:component-scan/> 或者 @ComponentScan

 都能處理@Configuration 註解的類。

 @Configuration 註解的 bean 都已經變成了增強的類

案例描述

@Bean 註解方法執行策略

@Configuration
public class MyBeanConfig {
 
    @Bean
    public Country country(){
        return new Country();
    }
 
    @Bean
    public UserInfo userInfo(){
        return new UserInfo(country());
    }
 
}

特別重要!!特別重要!!--》直接呼叫 country() 方法返回的是同一個例項,因為註解是@Configuration增強版本類

 

但是如果是變成@Component之後,此時返回的就不是一個例項了,每次都會建立一個例項

@Component 註解並沒有通過 cglib 來代理@Bean 方法的呼叫

@Component
public class MyBeanConfig {
 
    @Bean
    public Country country(){
        return new Country();
    }
 
    @Bean
    public UserInfo userInfo(){
        return new UserInfo(country());
    }
 
}

修正版本:此時也是一個例項(用@Autowired 注入)

  • 這種方式可以保證使用的同一個 Country 例項。
@Component
public class MyBeanConfig {
 
    @Autowired
    private Country country;
 
    @Bean
    public Country country(){
        return new Country();
    }
 
    @Bean
    public UserInfo userInfo(){
        return new UserInfo(country);
    }
 
}

===============================部分知識點=======================================

@Configuration 標記的類必須符合下面的要求:

  • 配置類必須以類的形式提供(不能是工廠方法返回的例項),允許通過生成子類在執行時增強(cglib 動態代理)。
  • 配置類不能是 final 類(沒法動態代理)。
  • 配置註解通常為了通過 @Bean 註解生成 Spring 容器管理的類,
  • 配置類必須是非本地的(即不能在方法中宣告,不能是 private)。
  • 任何巢狀配置類都必須宣告為static
  • @Bean 方法可能不會反過來建立進一步的配置類(也就是返回的 bean 如果帶有 @Configuration,也不會被特殊處理,只會作為普通的 bean)。