spring——自動裝配【非常詳細】
什麼是自動裝配?
自動裝配就是讓應用程式上下文為你找出依賴項的過程。說的通俗一點,就是Spring會在上下文中自動查詢,並自動給bean裝配與其關聯的屬性!
spring中實現自動裝配的方式有兩種,一種是通過xml檔案、另一種是通過註解。下面將為大家介紹這兩種方式實現自動裝配。
為了更簡單的讓大家理解,我們通過例子來說明:
有以下三個實體類,People類,Dog類,Cat類,分別代表人、狗、貓。人養了一隻狗和一隻貓,貓和狗都會叫。
public class Cat { public void shout(){ System.out.println("miao~"); } }
public class Dog { public void shout(){ System.out.println("wang wang~"); } }
public class Peopel { private Cat cat; private Dog dog; private String name; public Cat getCat() { return cat; } public void setCat(Cat cat) { this.cat = cat; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Peopel{" + "cat=" + cat + ", dog=" + dog + ", name='" + name + '\'' + '}'; } }
public class Peopel { private Cat cat; private Dog dog; private String name; public Cat getCat() { return cat; } public void setCat(Cat cat) { this.cat = cat; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Peopel{" + "cat=" + cat + ", dog=" + dog + ", name='" + name + '\'' + '}'; } }
手動裝配
講自動裝配之前,我們先來說一下手動裝配,手動裝配又是什麼?手動裝配就是手動的將bean中所關聯的其他bean裝配進去。用程式碼表示:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cat" class="com.kuang.pojo.Cat"/> <bean id="dog" class="com.kuang.pojo.Dog"/> <bean id="people" class="com.kuang.pojo.Peopel"> <property name="name" value="張三"/> <property name="cat" ref="cat"/> <property name="dog" ref="dog"/> </bean>
</beans>
在id=people的bean(以後id=xx的bean我們就叫xxBean)中,我們給peopleBean手動裝配了與之關聯的catBean和dogBean,這就叫做手動裝配。
那麼有沒有什麼辦法,我們可以不用去手動裝配關聯的bean,讓spring幫我們自動把關聯的bean裝配進去呢?答案是肯定的。自動裝配就可以幫助我們解決這個問題。實現自動裝配有兩種方式。一種是使用註解的方式、另一種是通過xml檔案的方式。下面我們倆講實現自動裝配的兩種方式。
方式一:通過xml檔案實現自動裝配
我們只需要在xml配置檔案中的bean標籤中加入一個屬性autowire即可,例如:
<bean id="people" class="com.kuang.pojo.Peopel" autowire="byName"> <property name="name" value="張三"/> </bean>
使用autowire關鍵字宣告bean的自動裝配方式。其可選值為byName、byType、constructor,default,no;這裡講前邊兩個。
1.byName
設定autowire屬性為byName,那麼Spring會根據class屬性找到實體類,然後查詢實體類中所有setter方法的名字,根據setter方法後面的名字(例如SetDog,則setter方法後面的名字為dog)再到配置檔案中尋找一個與該名字相同id的Bean,注入進來。如圖:
2.byType
設定autowire屬性為byType,那麼Spring會自動尋找一個與該屬性型別相同的Bean,注入進來。
*注意:使用byType這種方式,必須保證配置檔案中所有bean的class屬性的值是唯一的,否則就會報錯
例如:下邊這種方式是錯誤的,因為兩個bean中的class屬性的值重複了,會報錯
方式二:通過註解實現自動裝配
註解是通過反射來實現的。
1.使用註解前的準備:
要使用註解,xml檔案要使用如下的檔案頭:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> </beans>
注意:
<conteext:annotation-config/> 必須要寫在xml中,這是用來開啟註解的支援,如果不加上註解就無效。
2.使用
2.1 Autowired註解【常用】
首先xml配置檔案如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <bean id="cat" class="com.kuang.pojo.Cat"/> <bean id="dog" class="com.kuang.pojo.Dog"/> <bean id="people" class="com.kuang.pojo.Peopel"> <property name="name" value="張三"/> </bean> </beans>
然後在實體類的對應屬性上新增@Autowired註解(也可以把註解放到對應屬性的setter上),people類中依賴Dog類和Cat類。所以在people類中的dog和cat屬性上要加上@Autowired,實現自動裝配。
例如:
public class Peopel { @Autowired private Cat cat; @Autowired private Dog dog; private String name; public Cat getCat() { return cat; } public void setCat(Cat cat) { this.cat = cat; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Peopel{" + "cat=" + cat + ", dog=" + dog + ", name='" + name + '\'' + '}'; } }
public class Peopel { @Autowired private Cat cat; @Autowired private Dog dog; private String name; public Cat getCat() { return cat; } public void setCat(Cat cat) { this.cat = cat; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Peopel{" + "cat=" + cat + ", dog=" + dog + ", name='" + name + '\'' + '}'; } }
**重點:
(1)註解方法裝配屬性的過程:spring會預設優先根據(被註解修飾的)屬性型別去容器中找對應的元件(bean),找到就賦值;若找到多個相同型別的元件,再將屬性的名稱作為元件(bean)的id去容器中查詢。
(2)@Qualifier註解可以和使用Autowired搭配使用:@Qualifier指定需要裝配的元件的id,而不是使用屬性名。例如下邊例子,spring就會優先在容器中查詢id為“abcd”的元件。
public class Peopel { @Autowired @Qualifier(value = "cat") private Cat cat; }
public class Peopel { @Autowired @Qualifier(value = "cat") private Cat cat; }
什麼情況會使用到@Qualifier註解:當ioc容器根據屬性型別去容器中找找到多個相同型別的元件,再將屬性的名稱作為元件(bean)的id去容器中查詢找不到時就是用這兩個註解搭配,指定需要裝配的bean的id。
(3)在預設情況下使用@Autowired註釋進行自動注入時,Spring 容器中匹配的候選 Bean 數目必須有且僅有一個。當找不到一個匹配的 Bean 時,Spring 容器將丟擲 BeanCreationException 異常,並指出必須至少擁有一個匹配的 Bean。當不能確定 Spring 容器中一定擁有某個類的 Bean 時,可以在需要自動注入該類 Bean 的地方可以使用@Autowired(required=false)。這等於告訴 Spring:在找不到匹配 Bean 時也不報錯。
2.2. Resource註解【不常用】
@Resource:可以和@Autowired一樣實現自動裝配功能,但是跟@Autowired不一樣的是,它預設是按照元件名稱進行裝配的,按照元件名稱找不到在根據屬性型別去查詢,再找不到就報錯;他們另一個不同的地方就是@Autowired是Spring定義的; @Resource是java規範。
把每一件簡單的事情做好,就是不簡單;把每一件平凡的事情做好,就是不平凡!相信自己,創造奇蹟~~