spring 框架说明文档学习记录(3.2)
来源:互联网 发布:淘宝店铺权重 编辑:程序博客网 时间:2024/06/06 08:54
三.二 依赖
依赖注入
依赖注入(DI)是指对象仅通过构造函数参数、工厂方法参数或在从工厂方法构造或返回对象实例上设置的属性来定义它们的依赖关系的过程。容器在创建bean时注入这些依赖。这个过程基本上是bean自身通过构造函数或服务定位来控制实例化的反转。
通过DI规则,代码更整洁,同时当提供依赖后,解耦使代码变得更高效。对象不需要查找依赖,也不知道它所依赖对象的位置。因此,你的类变得更容易测试,特别是对接口和抽象类的依赖。
DI主要通过两种方式:基于构造函数的依赖注入和基于Setter的依赖注入
基于构造函数的依赖注入
基于构造函数的DI,是通过容器调用拥有一系列代表依赖的参数的构造函数来实现的。
示例:基本pojo
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...}
构造函数参数解决方式
构造函数参数通过参数类型进行匹配
如果在bean定义中,没有潜在模糊的参数,bean实例化时,构造函数被提供的参数按照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>
当使用简单类型数据作为构造函数参数时,没有额外帮助,spring不能决定如何进行匹配,所以需要显示的指定参数类型
package examples;public class ExampleBean { // Number of years to 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>
为了清晰区分参数,我们也可以使用构造函数参数的名称
<bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg name="years" value="7500000"/> <constructor-arg name="ultimateAnswer" value="42"/></bean>
需要注意的是,为了保证spring能够从构造函数中查找参数名称,我们的编码必须以debug方式编译。如果不能使用debug方式编译,我们可以使用JDK注解@ConstructorProperties显式命名构造函数参数。
package examples;public class ExampleBean { // Fields omitted @ConstructorProperties({"years", "ultimateAnswer"}) public ExampleBean(int years, String ultimateAnswer) { this.years = years; this.ultimateAnswer = ultimateAnswer; }}
基于setter的依赖注入
<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"/>
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; }}
ApplicationContext支持基于构造函数和基于setter的依赖注入,同时也支持两者的同时使用。一般基于构造函数的依赖用来处理强制性依赖,setter方法和配置方法用来处理可选性依赖。注意,在setter方法上使用@Required注解,可以将一个属性标识为必需属性。
依赖方案的过程
- ApplicationContext使用描述所有beans的配置元数据进行创建和初始化。
- 对每一个bean,它的依赖是通过属性、构造函数参数或静态工厂方法参数的形式进行展示。这些依赖在bean创建时就提供给他。
- 每一个属性或参数,都是一个实际值或容器中另一个bean的引用。
- 每一个简单类型的属性或参数,赋值时都将它的类型转换为属性或参数的实际类型。Spring默认将string格式的简单类型转换为内置类型(int,long,String,boolean等)
依赖注入示例
基于setter
<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"/>
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; }}
基于构造函数
<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"/>
public class ExampleBean { private AnotherBean beanOne; private YetAnotherBean beanTwo; private int i; public ExampleBean(AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) { this.beanOne = anotherBean; this.beanTwo = yetAnotherBean; this.i = i; }}
基于静态工厂方法
<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; }}
- spring 框架说明文档学习记录(3.2)
- spring 框架说明文档学习记录(1)
- spring 框架说明文档学习记录(2)
- spring 框架说明文档学习记录(3)
- spring 框架说明文档学习记录(3.1)
- spring 框架说明文档学习记录(3.3)
- spring 框架说明文档学习记录(3.4)
- spring 框架说明文档学习记录(3.5)
- spring 框架说明文档学习记录(3.6)
- spring 框架说明文档学习记录(3.7)
- Spring框架学习记录
- Spring-Validator 说明文档
- Spring-Validator 说明文档
- Spring说明文档翻译1——第一部分,spring框架预览
- spring框架说明
- Spring Framework 5.0.0.M3中文文档 翻译记录 Part I. Spring框架概览1-2.2
- Spring的定时器说明文档
- Spring Framework 中文说明文档
- 如何在Mac上开启NTFS读取支持
- hive-2.1.1报错Failed to start database 'metastore_db' with class loader sun.misc.Launcher$AppClassLoad
- js判断360浏览器
- 448. Find All Numbers Disappeared in an Array
- 第一节 了解h5
- spring 框架说明文档学习记录(3.2)
- 360前端星计划(一)
- webdriver+selenium面试总结
- mysql Access denied for user……
- python自然语言处理学习笔记二
- 高并发
- app widget简单用法(3)
- RocketMQ使用P2P(点对点)消息传送模式,生产端生产一个消息,消费端消费几乎同时收到两个相同消息
- 自定义注解, 完美代替findViewById()