通過注解注入bean
背景
我們談到spring的時候一定會提到ioc容器、di依賴注入,spring通過將一個個類標注為bean的方法注入到ioc容器中,達到了控制反轉的效果。那么我們剛開始接觸bean的時候,一定是使用xml文件,一個一個的注入,就例如下面這樣。
1
|
<bean id= "bean" class = "beandemo.bean" /> |
我們的項目一般很大的話,就需要成千上百個bean去使用,這樣寫起來就很繁瑣。那么spring就幫我們實現了一種通過注解來實現注入的方法。只需要在你需要注入的類前面加上相應的注解,spring就會幫助我們掃描到他們去實現注入。
xml掃描包的方式
1
|
<context:component-scan base- package = "com.company.beandemo" /> |
通過注解注入的一般形式
一般情況下,注入bean有一個最直白,最易懂的方式去實現注入,下面廢話先不多說,先貼代碼。
bean類
1
2
|
public class mybean{ } |
configuration類
1
2
3
4
5
6
7
8
9
|
//創建一個class配置文件 @configuration public class myconfiguration{ //將一個bean交由spring進行管理 @bean public mybean mybean(){ return new mybean(); } } |
test類
與xml有一點不同,這里在test中,實例化的不再是classpathxmlapplicationcontext,而是獲取的annotationconfigapplicationcontext實例。
1
2
3
|
applicationcontext context = new annotationconfigapplicationcontext(myconfiguration. class ); mybean mybean = 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類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@component public class mybeanconstructor { private anotherbean anotherbeanconstructor; @autowired public mybeanconstructor(anotherbean anotherbeanconstructor){ this .anotherbeanconstructor = anotherbeanconstructor; } @override public string tostring() { return "mybean{" + "anotherbeanconstructor=" + anotherbeanconstructor + '}' ; } } |
anotherbean類
1
2
3
|
@component (value= "bean的id,默認為類名小駝峰" ) public class anotherbean { } |
configuration類
1
2
3
4
|
@configuration @componentscan ( "com.company.annotationbean" ) public class myconfiguration{ } |
這里我們可以發現,和一般方式注入的代碼不一樣了,我們來看看新的注解都是什么意思:
@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類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@component public class mybeanset { private anotherbean anotherbeanset; @autowired public void setanotherbeanset(anotherbean anotherbeanset) { this .anotherbeanset = anotherbeanset; } @override public string tostring() { return "mybeanset{" + "anotherbeanset=" + anotherbeanset + '}' ; } } |
configuration類 和 test類
同上一個,就不貼了
這里我們發現在setter方法上我們有一個@autowired,與上面不同的是,我們不會在實例化該類時就自動裝配:wrench:這個對象,而是在顯式調用setter的時候去裝配。
通過屬性去注入bean
我們前面兩種注入的方式諸如時間不同,并且代碼較多,若是通過屬性,即就是
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@component public class mybeanproperty { @autowired private anotherbean anotherbeanproperty; @override public string tostring() { return "mybeanproperty{" + "anotherbeanproperty=" + anotherbeanproperty + '}' ; } } |
這里我們可以看到我們這個類中需要使用anotherbean這個實例對象,我們可以通過@autowired去自動裝配它。
對于有些小伙伴問私有屬性,spring怎么去加載它到ioc的?推薦去看看反射
通過list注入bean
mybeanlist類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@component public class mybeanlist { private list<string> stringlist; @autowired public void setstringlist(list<string> stringlist) { this .stringlist = stringlist; } public list<string> getstringlist() { return stringlist; } } |
myconfiguration類
1
2
3
4
5
6
7
8
9
10
11
12
|
@configuration @componentscan ( "annobean.annotationbean" ) public class myconfiguration { @bean public list<string> stringlist(){ list<string> stringlist = new arraylist<string>(); stringlist.add( "list-1" ); stringlist.add( "list-2" ); return stringlist; } } |
這里我們將mybeanlist進行了注入,對list中的元素會逐一注入。下面介紹另一種方式注入list
myconfiguration類
1
2
3
4
5
6
7
8
9
10
11
12
|
@bean //通過該注解設定bean注入的優先級,不一定連續數字 @order ( 34 ) public string string1(){ return "string-1" ; } @bean @order ( 14 ) public string string2(){ return "string-2" ; } |
注入與list中泛型一樣的類型,會自動去匹配類型,及時這里沒有任何list的感覺,只是string的類型,但他會去通過list的bean的方式去注入。
第二種方式的優先級高于第一種,當兩個都存在的時候,若要強制去使用第一種方式,則要去指定bean的id即可
通過map去注入bean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@component public class mybeanmap { private map<string,integer> integermap; public map<string, integer> getintegermap() { return integermap; } @autowired public void setintegermap(map<string, integer> integermap) { this .integermap = integermap; } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@bean public map<string,integer> integermap(){ map<string,integer> integermap = new hashmap<string, integer>(); integermap.put( "map-1" , 1 ); integermap.put( "map-2" , 2 ); return integermap; } @bean public integer integer1(){ return 1 ; } @bean public integer integer2(){ return 2 ; } |
同樣這里也具有兩種方式去注入map類型bean,且第二種的優先值高于第一種
以上就是bean通過注解注入的幾種方式,大家可以對比著xml注入的方式去看。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對服務器之家的支持。
原文鏈接:https://juejin.im/post/5ca81a536fb9a05e6538aa39