深刻解析Java的Spring框架中bean的依附注入。本站提示廣大學習愛好者:(深刻解析Java的Spring框架中bean的依附注入)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻解析Java的Spring框架中bean的依附注入正文
每個基於java的運用法式都有一個配合任務來展現給用戶看到的內容作為任務的運用幾個對象。當編寫一個龐雜的Java運用法式,運用法式類應當盡量自力其他Java類來增長反復應用這些類,並自力於其他種別的測試它們,而如許做單位測試的能夠性。依附注入(或有時稱為布線)有助於粘合這些類在一路,同時堅持他們的自力。
斟酌有個中有一個文本編纂器組件的運用法式,要供給拼寫檢討。尺度的代碼將看起來像如許:
public class TextEditor { private SpellChecker spellChecker; public TextEditor() { spellChecker = new SpellChecker(); } }
我們在這裡所做的就是創立文本編纂和拼寫檢討之間的依附性。在掌握計劃中的反轉,我們反而會做如許的工作:
public class TextEditor { private SpellChecker spellChecker; public TextEditor(SpellChecker spellChecker) { this.spellChecker = spellChecker; } }
在這裡,文本編纂不該該擔憂拼寫檢討落實。拼寫檢討器將自力實行,將供給給文本編纂在文本編纂實例化的時刻,這全部進程是由Spring框架的掌握。
在這裡,我們曾經刪除從文本編纂的周全掌握,並堅持它在其他處所(即XML設置裝備擺設文件)和依附性(即類拼寫檢討)被注入到類文本編纂經由過程類結構函數。是以,流程掌握曾經“倒”經由過程依附注入(DI),由於曾經有用地委派依附一些內部體系。
依附注入的第二種辦法是經由過程文本編纂類,我們將創立拼寫檢討實例的setter辦法,該實例將被用來挪用setter辦法來初始化文本編纂的屬性。
是以,DI重要有兩種變體和上面的兩個子章將涵蓋二者聯合實例:
基於結構函數的依附注入
當容器挪用類的結構函數有多個參數,每一個代表在其他類中的結構函數依附關系為基本的DI來完成。
例子:
上面的例子顯示了一個類文本編纂TextEditor 只能是依附注入與結構函數注入。
我們應用Eclipse IDE,然後依照上面的步調來創立一個Spring運用法式:
這裡是TextEditor.java文件的內容:
package com.yiibai; public class TextEditor { private SpellChecker spellChecker; public TextEditor(SpellChecker spellChecker) { System.out.println("Inside TextEditor constructor." ); this.spellChecker = spellChecker; } public void spellCheck() { spellChecker.checkSpelling(); } }
上面是別的一個相干的類文件SpellChecker.java內容:
package com.yiibai; public class SpellChecker { public SpellChecker(){ System.out.println("Inside SpellChecker constructor." ); } public void checkSpelling() { System.out.println("Inside checkSpelling." ); } }
以下是MainApp.java文件的內容:
package com.yiibai; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); TextEditor te = (TextEditor) context.getBean("textEditor"); te.spellCheck(); } }
以下是設置裝備擺設文件beans.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- Definition for textEditor bean --> <bean id="textEditor" class="com.yiibai.TextEditor"> <constructor-arg ref="spellChecker"/> </bean> <!-- Definition for spellChecker bean --> <bean id="spellChecker" class="com.yiibai.SpellChecker"> </bean> </beans>
創立源代碼和bean設置裝備擺設文件完成後,讓我們運轉運用法式。假如一切順遂將打印以下信息:
Inside SpellChecker constructor. Inside TextEditor constructor. Inside checkSpelling.
結構函數的參數解析:
能夠有歧義存在,而將參數傳遞給結構函數的情形下有一個以上的參數。要處理這類不肯定性,個中的結構器參數在一個bean界說中界說的次序就是這些參數供給給恰當的結構函數的次序。請斟酌上面的類:
package x.y; public class Foo { public Foo(Bar bar, Baz baz) { // ... } }
上面的設置裝備擺設任務正常:
<beans> <bean id="foo" class="x.y.Foo"> <constructor-arg ref="bar"/> <constructor-arg ref="baz"/> </bean> <bean id="bar" class="x.y.Bar"/> <bean id="baz" class="x.y.Baz"/> </beans>
讓我們檢討一個更多情形下我們經由過程分歧類型的結構函數。請斟酌上面的類:
package x.y; public class Foo { public Foo(int year, String name) { // ... } }
容器也能夠應用類型婚配與簡略類型,假如你明白地指定應用type屬性的結構函數的參數類型。例如:
<beans> <bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg type="int" value="2001"/> <constructor-arg type="java.lang.String" value="Zara"/> </bean> </beans>
最初,並經由過程結構函數參數的最好辦法,應用索引屬性來顯式地指定一個結構器參數的索引。這裡的索引是從0開端。例如:
<beans> <bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg index="0" value="2001"/> <constructor-arg index="1" value="Zara"/> </bean> </beans>
最初須要解釋的,假如你傳遞一個援用到一個對象,須要應用<constructor-arg>標簽的ref屬性,假如是直接傳遞一個值,那末應當應用value屬性。
基於setter辦法的依附注入
基於setter DI由容器挪用setter辦法對bean挪用無參結構器或無參static工場辦法實例化bean以後完成。
這裡是TextEditor.java文件的內容:
package com.yiibai; public class TextEditor { private SpellChecker spellChecker; // a setter method to inject the dependency. public void setSpellChecker(SpellChecker spellChecker) { System.out.println("Inside setSpellChecker." ); this.spellChecker = spellChecker; } // a getter method to return spellChecker public SpellChecker getSpellChecker() { return spellChecker; } public void spellCheck() { spellChecker.checkSpelling(); } }
在這裡,須要檢討setter辦法的定名商定。設置我們應用setSpellChecker()辦法,這長短常相似於Java POJO類的變量的拼寫檢討器。讓我們發明另外一個相干的類文件SpellChecker.java,內容以下:
package com.yiibai; public class SpellChecker { public SpellChecker(){ System.out.println("Inside SpellChecker constructor." ); } public void checkSpelling() { System.out.println("Inside checkSpelling." ); } }
以下是MainApp.java文件的內容:
package com.yiibai; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); TextEditor te = (TextEditor) context.getBean("textEditor"); te.spellCheck(); } }
以下是設置裝備擺設文件beans.xml文件外面有設置裝備擺設為基於setter辦法注入:
<?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 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- Definition for textEditor bean --> <bean id="textEditor" class="com.yiibai.TextEditor"> <property name="spellChecker" ref="spellChecker"/> </bean> <!-- Definition for spellChecker bean --> <bean id="spellChecker" class="com.yiibai.SpellChecker"> </bean> </beans>
應當留意在基於結構函數注入和setter注入界說beans.xml文件的差別。獨一的差別是,我們曾經應用<constructor-arg>標簽為基於結構函數的注入和的<property>標簽為基於setter注入的<bean>元素內。
須要留意的第二個主要的一點是,假如傳遞一個援用到一個對象,須要應用<property>標簽的ref屬性,假如是直接傳遞一個值,那末應當應用value屬性。
創立源代碼和bean設置裝備擺設文件完成後,讓我們運轉運用法式。假如一切順遂,這將打印以下信息:
Inside SpellChecker constructor. Inside setSpellChecker. Inside checkSpelling.
采取p稱號空間的XML設置裝備擺設:
假如你有許多的setter辦法則可以很便利地應用p稱號空間的XML設置裝備擺設文件中。讓我們檢查他們的差別:
讓我們來用的<property>標簽尺度的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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="john-classic" class="com.example.Person"> <property name="name" value="John Doe"/> <property name="spouse" ref="jane"/> </bean> <bean name="jane" class="com.example.Person"> <property name="name" value="John Doe"/> </bean> </beans>
下面的XML設置裝備擺設可重寫應用 p-namespace以下一個簡練的辦法:
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="john-classic" class="com.example.Person" p:name="John Doe" p:spouse-ref="jane"/> </bean> <bean name="jane" class="com.example.Person" p:name="John Doe"/> </bean> </beans>
在這裡,不該該在指定原始值和對空間對象援用的差別。-ref部門表現,這不是直鏈的值,而是一個援用到另外一個bean中。