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;  }}











0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手动档汽车离合抱死怎么办 别克gl8后轮吃胎怎么办 扭力梁后轮吃胎怎么办 非独立悬挂吃胎怎么办 货车半轴法兰盘裂纹怎么办 小天才平板裂屏了怎么办 新车撞了个坑怎么办 新车碰了个坑怎么办 汽车顶被砸了个坑怎么办 途观l前减震异响怎么办 锦明8代声音太大怎么办 手机网页无法加载插件怎么办 微信公众号被投诉怎么办 住了酒店的尾房怎么办 喜欢前任的闺蜜怎么办 闺蜜给介绍对象怎么办 喜欢对象的发小怎么办 山东省直医保卡丢失怎么办 高铁票如果错过了怎么办 动车错过了时间怎么办 长途动车错过了怎么办 动车如果错过了怎么办 没有取票错过了怎么办 动车出站没检票怎么办 火车晚点耽误了下班车怎么办 动车票中途丢了怎么办 购买二手房异地铁路公积金怎么办 沈阳公积金卡丢了怎么办 住宅专项维修资金用完了怎么办 广州出租车丢了东西怎么办 广州的士丢了东西怎么办 网上找兼职被骗了怎么办 海信空调开不了机怎么办 海信空调遥控器开不了怎么办 学生遭套路贷反被仲裁怎么办 赏脸打错字尝脸怎么办 红掌的花变黑了怎么办 红掌花苞发黑了怎么办 水培植物腐根了怎么办 水培绿萝水发臭怎么办 水里养花根烂掉怎么办