依赖:
典型的企业应用程序不可能由单个对象(在spring中,也可称之bean)组成,再简单的应用也是由几个对象相互配合工作的,这一章主要介绍bean的定义以及bean之间的相互协作。
依赖注入:
spring中的依赖注入(Dependency injection (DI))主要有两种形式:构造器注入和setter方法注入。
构造器注入:
基于构造函数的方式有其自己的优势,它可以明白地创建出带有特定构造參数的对象。另外它对于创建一些在类中不须要常常变化的域有明显的优势。假设用setter方法来做这样的事情会显得非常不协调。但通常可以採用init的方法在创建时就将其初始化。
当然对于某些类可能有非常多的域,构造函数不可能包括全部的情况,并且当中可以包括的构造參数也是有限的,此时Setter方法注入就可以以发挥其余地。
下面演示样例是一个仅仅能通过构造器注入的类:
plain copy
- public class SimpleMovieLister {
- // the SimpleMovieLister has a dependency on a MovieFinder
- private MovieFinder movieFinder;
- // a constructor so that the Spring container can 'inject' a MovieFinder
- public SimpleMovieLister(MovieFinder movieFinder) {
- this.movieFinder = movieFinder;
- }
- // business logic that actually 'uses' the injected MovieFinder is omitted...
- }
构造函数參数匹配时根据的是构造器參数类型,为了不产生歧义,一般构造參数给出的顺序依照构造函数中參数给定的顺序。例如以下:
plain copy
- package x.y;
- public class Foo {
- public Foo(Bar bar, Baz baz) {
- // ...
- }
- }
没有潜在的歧义存在,如果Bar和Baz两个类不想关
plain copy
- <span style="color:#333333;"><beans>
- <bean id="foo" class="x.y.Foo">
- <</span><span style="color:#ff0000;">constructor-arg</span><span style="color:#333333;"> ref="bar"/>
- <constructor-arg ref="baz"/>
- </bean>
- <bean id="bar" class="x.y.Bar"/>
- <bean id="baz" class="x.y.Baz"/>
- </beans></span>
当还有一个bean被引用时,假设类型一直,匹配就能够发生。当一个简单类型使用时,比如<value>true<value>,Spring不能决定value的类型。就不能进行匹配。
看以下一个演示样例:
plain copy
- 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;
- }
- }
在前面这个演示样例中,使用type属性。容器能够进行简单的类型匹配:
plain copy
- <bean id="exampleBean" class="examples.ExampleBean">
- <constructor-arg type="int" value="7500000"/>
- <constructor-arg type="java.lang.String" value="42"/>
- </bean>
相同。我们也能够使用index属性来指定參数顺序(注意index从0開始):
plain copy
- <bean id="exampleBean" class="examples.ExampleBean">
- <constructor-arg index="0" value="7500000"/>
- <constructor-arg index="1" value="42"/>
- </bean>
在spring3.0中,我们也能够使用构造器參数名字来制定相应的參数值:
plain copy
- <bean id="exampleBean" class="examples.ExampleBean">
- <constructor-arg name="years" value="7500000"/>
- <constructor-arg name="ultimateanswer" value="42"/>
- </bean>
注意:Keep in mind that to make this work out of the box your code must be compiled with the debug flag enabled so that Spring can look up the parameter name from the constructor.
If you can't compile your code with debug flag (or don't want to) you can use @ConstructorProperties
JDK
annotation to explicitly name your constructor arguments. The sample class would then have to look as follows:
plain copy
- package examples;
- public class ExampleBean {
- // Fields omitted
- @ConstructorProperties({"years", "ultimateAnswer"})
- public ExampleBean(int years, String ultimateAnswer) {
- this.years = years;
- this.ultimateAnswer = ultimateAnswer;
- }
- }
setter方法注入:
下面是一个简单的仅仅能用setter方法进行注入的样例:
plain copy
- public class SimpleMovieLister {
- // the SimpleMovieLister has a dependency on the MovieFinder
- private MovieFinder movieFinder;
- // a setter method so that the Spring container can 'inject' a MovieFinder
- public void setMovieFinder(MovieFinder movieFinder) {
- this.movieFinder = movieFinder;
- }
- // business logic that actually 'uses' the injected MovieFinder is omitted...
- }
ApplicationContext
支持setter注入和构造器注入,也支持在已存在构造器注入的情况下继续进行setter注入。
依赖注入实例:
下面样例为setter注入的xml配置文件:
plain copy
- <bean id="exampleBean" class="examples.ExampleBean">
- <!-- setter injection using the nested <ref/> element -->
- <property name="beanOne"><ref bean="anotherExampleBean"/></property>
- <!-- setter injection using the neater 'ref' attribute -->
- <property name="beanTwo" ref="yetAnotherBean"/>
- <property name="integerProperty" value="1"/>
- </bean>
- <bean id="anotherExampleBean" class="examples.AnotherBean"/>
- <bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
plain copy
- public class ExampleBean {
- private AnotherBean beanOne;
- private YetAnotherBean beanTwo;
- private int i;
- public void setBeanOne(AnotherBean beanOne) {
- this.beanOne = beanOne;
- }
- public void setBeanTwo(YetAnotherBean beanTwo) {
- this.beanTwo = beanTwo;
- }
- public void setIntegerProperty(int i) {
- this.i = i;
- }
- }
上面这个样例使用的是setter注入。
以下是构造器注入的一个样例:
plain copy
- <bean id="exampleBean" class="examples.ExampleBean">
- <!-- constructor injection using the nested <ref/> element -->
- <constructor-arg>
- <ref bean="anotherExampleBean"/>
- </constructor-arg>
- <!-- constructor injection using the neater 'ref' attribute -->
- <constructor-arg ref="yetAnotherBean"/>
- <constructor-arg type="int" value="1"/>
- </bean>
- <bean id="anotherExampleBean" class="examples.AnotherBean"/>
- <bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
plain copy