3.4.1 依賴注入
依賴注入兩種方式:基於構造器的DI、基於setter方法的DI。
3.4.1.1 基於構造器的DI
參數是引入對象,且之前不存在父-子類關係:
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>當使用簡單類型時,spring不好確定value的類型。
package examples; public class ExampleBean { // No. of years to the calculate the Ultimate Answer private int years; // The Answer to Life, the Universe, and Everything private String ultimateAnswer; public ExampleBean(int years, String ultimateAnswer) { this.years = years; this.ultimateAnswer = ultimateAnswer; } }
<bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg type="int" value="7500000"/> <constructor-arg type="java.lang.String" value="42"/> </bean>或者可以使用index來指定參數要按照什麼樣的順序設置。
<bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg index="0" value="7500000"/> <constructor-arg index="1" value="42"/> </bean>對spirng3.0來講,還可以使用name來指定要設置的屬性名。
<bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg name="years" value="7500000"/> <constructor-arg name="ultimateanswer" value="42"/> </bean>要讓這個方法生效,要記得:your code must be compiled with the debug flag enabled(啥意思?)或者要使用@ConstructorProperties:
package examples; public class ExampleBean { // Fields omitted @ConstructorProperties({"years", "ultimateAnswer"}) public ExampleBean(int years, String ultimateAnswer) { this.years = years; this.ultimateAnswer = ultimateAnswer; } }3.4.1.2 基於setter方法的DI
3.4.1.3 依賴解析過程
容器在創建之後,會對每個bean進行驗證,包括驗證bean引用的屬性是否是有效的。但是bean引用的properties只有在bean創建之後纔會被創建。單例bean在容器被創建的時候就被創建,其他的bean只有在被請求才有用到。
Spring設置properties或者解決依賴儘可能的晚。
A依賴於B,那麼B會先被創建,然後才創建A。
3.4.1.4 DI例子
使用靜態工廠方法,傳參數。
<bean id="exampleBean" class="examples.ExampleBean" factory-method="createInstance"> <constructor-arg ref="anotherExampleBean"/> <constructor-arg ref="yetAnotherBean"/> <constructor-arg value="1"/> </bean> <bean id="anotherExampleBean" class="examples.AnotherBean"/> <bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
public class ExampleBean { // a private constructor private ExampleBean(...) { ... } // a static factory method; the arguments to this method can be // considered the dependencies of the bean that is returned, // regardless of how those arguments are actually used. public static ExampleBean createInstance ( AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) { ExampleBean eb = new ExampleBean (...); // some other operations... return eb; } }