1. 程式人生 > 其它 >7 種 Spring Boot 注入 Bean 的方式

7 種 Spring Boot 注入 Bean 的方式

  • 背景
  • 通過註解注入的一般形式
  • 通過構造方法注入Bean
  • 通過set方法注入Bean
  • 通過屬性去注入Bean
  • 通過List注入Bean
  • 通過Map去注入Bean

背景

我們談到Spring的時候一定會提到IOC容器、DI依賴注入,Spring通過將一個個類標註為Bean的方法注入到IOC容器中,達到了控制反轉的效果。那麼我們剛開始接觸Bean的時候,一定是使用xml檔案,一個一個的注入,就例如下面這樣。

<beanid="bean"class="beandemo.Bean"/>

我們的專案一般很大的話,就需要成千上百個Bean去使用,這樣寫起來就很繁瑣。那麼Spring就幫我們實現了一種通過註解來實現注入的方法。只需要在你需要注入的類前面加上相應的註解,Spring就會幫助我們掃描到他們去實現注入。

xml掃描包的方式

<context:component-scanbase-package="com.company.beandemo"/>

通過註解注入的一般形式

一般情況下,注入Bean有一個最直白,最易懂的方式去實現注入,下面廢話先不多說,先貼程式碼。


  • Bean類
publicclassMyBean{
}

  • Configuration類
//建立一個class配置檔案
@Configuration
publicclassMyConfiguration{
//將一個Bean交由Spring進行管理
@Bean
publicMyBeanmyBean(){
returnnewMyBean();
}
}

  • Test類

與xml有一點不同,這裡在Test中,例項化的不再是ClassPathXmlApplicationContext,而是獲取的AnnotationConfigApplicationContext例項。

ApplicationContextcontext=newAnnotationConfigApplicationContext(MyConfiguration.class);
MyBeanmyBean=cotext.getBean("myBean",MyBean.class);
System.out.println("myBean="+myBean);


上面的程式碼中MyBean也就是我們需要Spring去管理的一個Bean,他只是一個簡單的類。而MyConfiguration中,我們首先用@Configuration註解去標記了該類,這樣標明該類是一個Spring的一個配置類,在載入配置的時候會去載入他。

在MyConfiguration中我們可以看到有一個方法返回的是一個MyBean的例項,並且該方法上標註著@Bean的註解,標明這是一個注入Bean的方法,會將下面的返回的Bean注入IOC。

通過構造方法注入Bean

我們在生成一個Bean例項的時候,可以使用Bean的構造方法將Bean實現注入。直接看程式碼


  • Bean類
@Component
publicclassMyBeanConstructor{

privateAnotherBeananotherBeanConstructor;

@Autowired
publicMyBeanConstructor(AnotherBeananotherBeanConstructor){
this.anotherBeanConstructor=anotherBeanConstructor;
}

@Override
publicStringtoString(){
return"MyBean{"+
"anotherBeanConstructor="+anotherBeanConstructor+
'}';
}
}

  • AnotherBean類
@Component(value="Bean的id,預設為類名小駝峰")
publicclassAnotherBean{
}

  • Configuration類
@Configuration
@ComponentScan("com.company.annotationbean")
publicclassMyConfiguration{
}


這裡我們可以發現,和一般方式注入的程式碼不一樣了,我們來看看新的註解都是什麼意思:

  • @AutoWired

簡單粗暴,富貴網直接翻譯過來的意思就是自動裝配:wrench:,還不理解為什麼叫自動裝配:wrench:?看了下一個註解的解釋你就知道了。若是在這裡注入的時候指定一個Bean的id就要使用@Qualifier註解

  • @Component(預設單例模式)

什麼??這翻譯過來是零件,怎麼感覺像是修汽車??是的,Spring管理Bean的方法就是修汽車的方式。我們在需要將一個類變成一個Bean被Spring可以注入的時候加上註解零件@Conmonent,那麼我們就可以在載入Bean的時候把他像零件一樣裝配:wrench:到這個IOC汽車上了

在這裡我們還有幾個其他的註解也可以實現這個功能,也就是細化的@Component:

  • @Controller 標註在Controller層

  • @Service 標註在Service層

  • @Repository 標註在dao層

  • @ComponentScan("")

還是翻譯,零件掃描,我們去看看括號裡的“零件倉庫”裡面,哪些“零件”(類)需要被裝載,Spring就會去掃描這個包,將裡面所有標註了@Component的類進行注入。

這裡的通過構造方法進行注入就很好理解了,我們在裝配MyBean這個零件的時候,突然發現他必須在AnotherBean的基礎上才能安裝到IOC裡面,那麼我們就在每次裝配MyBean的時候自動裝配:wrench:一個AnotherBean進去。舉個:chestnut:吧:

還是以汽車為例,我們在踩油門出發之前,是不是必須發車??這裡的AutoWired的內容就像發車,你不發車,這個油門你踩斷都沒有用,他都不會走。

通過set方法注入Bean

我們可以在一個屬性的set方法中去將Bean實現注入,看程式碼吧


  • MyBean類
@Component
publicclassMyBeanSet{

privateAnotherBeananotherBeanSet;

@Autowired
publicvoidsetAnotherBeanSet(AnotherBeananotherBeanSet){
this.anotherBeanSet=anotherBeanSet;
}

@Override
publicStringtoString(){
return"MyBeanSet{"+
"anotherBeanSet="+anotherBeanSet+
'}';
}
}

  • Configuration類 和 Test類

同上一個,就不貼了


這裡我們發現在setter方法上我們有一個@AutoWired,與上面不同的是,我們不會在例項化該類時就自動裝配:wrench:這個物件,而是在顯式呼叫setter的時候去裝配。

通過屬性去注入Bean

我們前面兩種注入的方式諸如時間不同,並且程式碼較多,若是通過屬性,即就是

@Component
publicclassMyBeanProperty{

@Autowired
privateAnotherBeananotherBeanProperty;

@Override
publicStringtoString(){
return"MyBeanProperty{"+
"anotherBeanProperty="+anotherBeanProperty+
'}';
}
}

這裡我們可以看到我們這個類中需要使用AnotherBean這個例項物件,我們可以通過@AutoWired去自動裝配它。

對於有些小夥伴問私有屬性,Spring怎麼去載入它到IOC的?推薦去看看反射

通過List注入Bean

  • MyBeanList類
@Component
publicclassMyBeanList{

privateList<String>stringList;

@Autowired
publicvoidsetStringList(List<String>stringList){
this.stringList=stringList;
}

publicList<String>getStringList(){
returnstringList;
}
}

  • MyConfiguration類
@Configuration
@ComponentScan("annoBean.annotationbean")
publicclassMyConfiguration{

@Bean
publicList<String>stringList(){
List<String>stringList=newArrayList<String>();
stringList.add("List-1");
stringList.add("List-2");
returnstringList;
}
}

這裡我們將MyBeanList進行了注入,對List中的元素會逐一注入。下面介紹另一種方式注入List

  • MyConfiguration類
@Bean
//通過該註解設定Bean注入的優先順序,不一定連續數字
@Order(34)
publicStringstring1(){
return"String-1";
}

@Bean
@Order(14)
publicStringstring2(){
return"String-2";
}

注入與List中泛型一樣的型別,會自動去匹配型別,及時這裡沒有任何List的感覺,只是String的型別,但他會去通過List的Bean的方式去注入。

第二種方式的優先順序高於第一種,當兩個都存在的時候,若要強制去使用第一種方式,則要去指定Bean的id即可

通過Map去注入Bean

@Component
publicclassMyBeanMap{

privateMap<String,Integer>integerMap;

publicMap<String,Integer>getIntegerMap(){
returnintegerMap;
}

@Autowired
publicvoidsetIntegerMap(Map<String,Integer>integerMap){
this.integerMap=integerMap;
}
}

@Bean
publicMap<String,Integer>integerMap(){
Map<String,Integer>integerMap=newHashMap<String,Integer>();
integerMap.put("map-1",1);
integerMap.put("map-2",2);
returnintegerMap;
}

@Bean
publicIntegerinteger1(){
return1;
}

@Bean
publicIntegerinteger2(){
return2;
}

同樣這裡也具有兩種方式去注入Map型別Bean,且第二種的優先值高於第一種

以上就是Bean通過註解注入的幾種方式,大家可以對比著xml注入的方式去看。