1. 程式人生 > >【Spring註解開發】元件註冊-使用@Configuration和@Bean給容器中註冊元件

【Spring註解開發】元件註冊-使用@Configuration和@Bean給容器中註冊元件

## 寫在前面 > 在之前的Spring版本中,我們只能通過寫XML配置檔案來定義我們的Bean,XML配置不僅繁瑣,而且很容易出錯,稍有不慎就會導致編寫的應用程式各種報錯,排查半天,發現是XML檔案配置不對!另外,每個專案編寫大量的XML檔案來配置Spring,也大大增加了專案維護的複雜度,往往很多個專案的Spring XML檔案的配置大部分是相同的,只有很少量的配置不同,這也造成了配置檔案上的冗餘。 > > 專案工程原始碼已經提交到GitHub:[https://github.com/sunshinelyz/spring-annotation](https://github.com/sunshinelyz/spring-annotation) ## Spring IOC和DI 在Spring容器的底層,最重要的功能就是IOC和DI,也就是控制反轉和依賴注入。 > IOC:控制反轉,將類的物件的建立交給Spring類管理建立。 > DI:依賴注入,將類裡面的屬性在建立類的過程中給屬性賦值。 > DI和IOC的關係:DI不能單獨存在,DI需要在IOC的基礎上來完成。 在Spring內部,所有的元件都會放到IOC容器中,元件之間的關係通過IOC容器來自動裝配,也就是我們所說的依賴注入。接下來,我們就使用註解的方式來完成容器元件的註冊、管理及依賴、注入等功能。 在介紹使用註解完成容器元件的註冊、管理及依賴、注入等功能之前,我們先來看看使用XML檔案是如何注入Bean的。 ## 通過XML檔案注入JavaBean 首先,我們在工程的io.mykit.spring.bean包下建立Person類,作為測試的JavaBean,程式碼如下所示。 ```java package io.mykit.spring.bean; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.io.Serializable; /** * @author binghe * @version 1.0.0 * @description 測試實體類 */ @Data @ToString @NoArgsConstructor @AllArgsConstructor public class Person implements Serializable { private static final long serialVersionUID = 7387479910468805194L; private String name; private Integer age; } ``` 接下來,我們在工程的resources目錄下建立Spring的配置檔案beans.xml,通過beans.xml檔案將Person類注入到Spring的IOC容器中,配置如下所示。 ```xml ``` 到此,我們使用XML方式注入JavaBean就配置完成了。接下來,我們建立一個SpringBeanTest類來進行測試,這裡,我使用的是Junit進行測試,測試方法如下所示。 ```java @Test public void testXmlConfig(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Person person = (Person) context.getBean("person"); System.out.println(person); } ``` 執行testXmlConfig()方法,輸出的結果資訊如下。 ```bash Person(name=binghe, age=18) ``` 從輸出結果中,我們可以看出,Person類通過beans.xml檔案的配置,已經注入到Spring的IOC容器中了。 ## 通過註解注入JavaBean 通過XML檔案,我們可以將JavaBean注入到Spring的IOC容器中。那使用註解又該如何實現呢?別急,其實使用註解比使用XML檔案要簡單的多,我們在專案的io.mykit.spring.plugins.register.config包下建立PersonConfig類,並在PersonConfig類上新增@Configuration註解來標註PersonConfig類是一個Spring的配置類,通過@Bean註解將Person類注入到Spring的IOC容器中。 ```java package io.mykit.spring.plugins.register.config; import io.mykit.spring.bean.Person; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @author binghe * @version 1.0.0 * @description 以註解的形式來配置Person */ @Configuration public class PersonConfig { @Bean public Person person(){ return new Person("binghe001", 18); } } ``` 沒錯,通過PersonConfig類我們就能夠將Person類注入到Spring的IOC容器中,是不是很Nice!!主要我們在類上加上@Configuration註解,並在方法上加上@Bean註解,就能夠將方法中建立的JavaBean注入到Spring的IOC容器中。 接下來,我們在SpringBeanTest類中建立一個testAnnotationConfig()方法來測試通過註解注入的Person類,如下所示。 ```java @Test public void testAnnotationConfig(){ ApplicationContext context = new AnnotationConfigApplicationContext(PersonConfig.class); Person person = context.getBean(Person.class); System.out.println(person); } ``` 執行testAnnotationConfig()方法,輸出的結果資訊如下所示。 ```bash Person(name=binghe001, age=18) ``` 可以看出,通過註解將Person類注入到了Spring的IOC容器中。 到這裡,我們已經明確,通過XML檔案和註解兩種方式都可以將JavaBean注入到Spring的IOC容器中。那麼,使用註解將JavaBean注入到IOC容器中時,使用的bean的名稱是什麼呢? 我們可以在testAnnotationConfig()方法中新增如下程式碼來獲取Person型別下的註解名稱。 ```java //按照型別找到對應的bean名稱陣列 String[] names = context.getBeanNamesForType(Person.class); Arrays.stream(names).forEach(System.out::println); ``` 完整的testAnnotationConfig()方法的程式碼如下所示。 ```java @Test public void testAnnotationConfig(){ ApplicationContext context = new AnnotationConfigApplicationContext(PersonConfig.class); Person person = context.getBean(Person.class); System.out.println(person); //按照型別找到對應的bean名稱陣列 String[] names = context.getBeanNamesForType(Person.class); Arrays.stream(names).forEach(System.out::println); } ``` 執行testAnnotationConfig()方法輸出的結果資訊如下所示。 ```bash Person(name=binghe001, age=18) person ``` 那這裡的person是啥?我們修改下PersonConfig類中的person()方法,將person()方法修改成person01()方法,如下所示。 ```java package io.mykit.spring.plugins.register.config; import io.mykit.spring.bean.Person; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @author binghe * @version 1.0.0 * @description 以註解的形式來配置Person */ @Configuration public class PersonConfig { @Bean public Person person01(){ return new Person("binghe001", 18); } } ``` 此時,我們再次執行testAnnotationConfig()方法,輸出的結果資訊如下所示。 ```bash Person(name=binghe001, age=18) person01 ``` 看到這裡,大家應該有種豁然開朗的感覺了,沒錯!!使用註解注入Javabean時,bean在IOC中的名稱就是使用@Bean註解標註的方法名稱。我們可不可以為bean單獨指定名稱呢?那必須可以啊!只要在@Bean註解中明確指定名稱就可以了。比如下面的PersonConfig類的程式碼,我們將person01()方法上的@Bean註解修改成@Bean("person")註解,如下所示。 ```java package io.mykit.spring.plugins.register.config; import io.mykit.spring.bean.Person; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @author binghe * @version 1.0.0 * @description 以註解的形式來配置Person */ @Configuration public class PersonConfig { @Bean("person") public Person person01(){ return new Person("binghe001", 18); } } ``` 此時,我們再次執行testAnnotationConfig()方法,輸出的結果資訊如下所示。 ```bash Person(name=binghe001, age=18) person ``` 可以看到,此時,輸出的JavaBean的名稱為person。 **結論:我們在使用註解方式向Spring的IOC容器中注入JavaBean時,如果沒有在@Bean註解中明確指定bean的名稱,就使用當前方法的名稱來作為bean的名稱;如果在@Bean註解中明確指定了bean的名稱,則使用@Bean註解中指定的名稱來作為bean的名稱。** 好了,咱們今天就聊到這兒吧!別忘了給個在看和轉發,讓更多的人看到,一起學習一起進步!! > 專案工程原始碼已經提交到GitHub:[https://github.com/sunshinelyz/spring-annotation](https://github.com/sunshinelyz/spring-annotation) ## 寫在最後 > 如果覺得文章對你有點幫助,請微信搜尋並關注「 **冰河技術** 」微信公眾號,跟冰河學習Spring註解驅動開發。公眾號回覆“spring註解”關鍵字,領取Spring註解驅動開發核心知識圖,讓Spring註解驅動開發不再