Spring第二天,你必須知道容器註冊元件的幾種方式!學廢它吊打面試官!

Cansluck發表於2020-11-17

前一篇《不要再說不會Spring了!Spring第一天,學會進大廠!》文章可點選下方連結進行回看。

不要再說不會Spring了!Spring第一天,學會進大廠!

 

今天將繼續講解Spring的註冊bean的方式。將通過程式碼片段+原始碼的方式,用圖文結合來講清楚這些註冊bean的方式。

 

一、@Conditional條件註冊bean

@Conditional:是Spring4新提供的註解,它的作用是按照一定條件進行判斷,滿足條件後往IOC容器中進行註冊。

場景:往IOC容器中註冊bean時,當作業系統為Windows時,註冊cansluck例項;當作業系統為Linux時,註冊xgx例項;此時用到@Conditional註解進行定製化條件選擇註冊bean。

例項:

新建WinCondition.java類作為條件類,用來處理作業系統為Windows的bean註冊;同時必須得實現Spring提供的Condition介面。

WinCondition.java類:

新建LinuxConditional條件類,用來處理作業系統為Linux的bean註冊。

LinuxConditional.java類:

來解析一下介面Condition,看下Condition介面的程式碼(JDK封裝):

介面中定義了一個抽象方法:matches(),返回true時,則意味著註冊被註解的bean,反之返回false。因此實現該介面時,都要實現該介面的matches抽象方法。

ConditionContext介面為獲取IOC容器或者物件工廠的介面,裡面提供了幾個抽象方法,如下圖:

可以看到提供了5個抽象方法,分別返回不同的物件。在這裡我們用到getEnvironment()獲取到當前編譯環境的方法,來結合場景配合@Conditional註解來使用。(有興趣的朋友可以自行擴充,比如獲取IOC容器bean可以使用getBeanFacroty()方法等等。)

 

回過頭來,我們在MainConfig.java配置類中,如果為windows環境,則將cansluck註冊到IOC容器中;如果為linux環境,則將xgx註冊到IOC容器中。下面用測試類來測試一下:

我們可以看到person是傳統@Bean註解進行了註冊,當前環境為windows環境,因此cansluck符合條件,因此將cansluck註冊到IOC容器中,xgx並沒有註冊到IOC容器。

如果不加@Conditional註解,則會將cansluck和xgx全部註冊到IOC容器中(這裡就不做演示了,有興趣的小夥伴可以自行去掉註解進行操作);因此當引入@Conditional註解時,容器可以選擇性註冊bean。

 

二、@Import註冊bean

上面講的基本上是@Bean的方式往IOC容器中註冊bean,那樣需要在配置類中新增多個對應bean的實現方法,這樣也會讓程式碼看起來非常的冗餘。因此Spring也提供了@Import註解的方式,可以按照陣列的形式,新增一個或者多個bean完成IOC容器中bean的註冊。

 

1. 使用@Import註解方式註冊bean

當前專案中,已經建立了一個Person實體類,並且通過@Bean的方式往IOC容器中註冊bean。

現在,分別再建立一個Dog 和 Cat 實體類,通過@Import的方式往IOC容器中註冊備案。

程式碼如下:

新建Dog.java 和 Cat.java 類

MainConfig.java配置類

這樣,就能夠不需要再寫@Bean的方式寫很多方法,而是可以通過@Import註解的方式,將一個或者多個類註冊往IOC容器中進行註冊。就省了很多重複程式碼工作量的過程。

 

2. 使用@ImportSelector註冊bean

使用@ImportSelector註解可以批量匯入元件的全類名陣列,自定義邏輯返回需要匯入元件對應ImportSelector.java類

程式碼如下:

新建Fish.java 和 Tiger.java類

CansluckImportSelector.java類

MainConfig.java配置類

Test測試類

通過測試類測試後可以看到,Fish和Tiger兩個實體類也被註冊到了IOC容器中。

 

3. 使用@ImportBeanDefinitionRegister註冊bean

使用@ImportBeanDefinitionRegister自定義註冊向IOC容器註冊bean。

新建Pig.java類

CansluckImportBeanDefinitionRegistrar.java類

(在上面的程式碼中,我們看到引用了RootBeanDefinition類物件進行例項化,在後續的持續學習中,會介紹到該類的一個原始碼介紹,而且會發現基本上都是用了這個類來進行bean的註冊)

MainConfig.java配置類

Test測試類

通過測試類測試後可以看到,Pig實體類也被註冊到了IOC容器中。

 

4. 通過實現FactoryBean介面來註冊bean

新建Monkey.java類

CansluckFactoryBean.java類

可以看到實現了FactoryBean介面,並實現了三個抽象方法。

可以先來看下FactoryBean的原始碼:

使用Spring提供的FactoryBean(工廠bean)介面,可以根據原始碼看到有三個抽象方法:

1. getObject()返回物件,把物件放到容器中;

2. getObjectType()返回物件型別;

3. isSingleton()是否單例進行控制

MainConfig.java配置類

在這裡採用了@​Bean的方式進行註冊,也可以在@Import中引入進行註冊

 

以上就是給容器註冊元件的​方式。有興趣的小夥伴可以根據案例自行嘗試並​閱讀原始碼進行分析。

 

給容器中註冊元件的方式總結

1. @Bean​:【匯入第三方的類或包的元件】

2. 包掃描 + 元件的標註註解(@ComponentScan: 針對@Controller、@Service、@Reponsitory、@Component),一般是針對我們自己寫的類使用該方式

3. @Import​:【快速給容器匯入一個或多個元件】,@Bean有點簡單

    ​① @Import(要匯入到容器中的元件)​:容器會自動註冊這個元件,其中註冊的bean的id為元件的全路徑類名(比如com.java.xxx.Person)

    ​② ​ImportSelector:是一個介面,返回需要匯入到容器的元件全類名陣列

    ​③ ImportBeanDefinitionRegistr​ar:可以手動新增元件到IOC容器中,所有Bean的註冊可以使用BeanDefinitionRegistry(例如寫CansluckBeanDefinitionRegistrar實現ImportBeanDefinitionRegistrar介面即可)

    ​④ 使用Spring提供的FactoryBean(工廠Bean)進行註冊

 

以上為Spring相關給容器中註冊元件的方式總結,小夥伴們有更多的一些建議和看法可以在下方進行留言​。

 

碼字不易,希望能夠點贊,關注,分享~謝謝啦

< END >

Java極客思維

微信掃一掃,關注公眾號

相關文章