加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Bean的两种依赖注入方式

发布时间:2020-12-13 22:15:03 所属栏目:百科 来源:网络整理
导读:依赖是指对象之间的关系,依赖注入的 两种主要方式: 基于构造器注入Constructor-based 基于setter方法注入Setter-based 经常会有同学把依赖注入和bean实例化搞混。实例化是创建对象,相当于new这个操作符;而依赖注入是注入对象 方法的参数 或对象的 属性

依赖是指对象之间的关系,依赖注入的两种主要方式:

基于构造器注入Constructor-based

基于setter方法注入Setter-based


经常会有同学把依赖注入和bean实例化搞混。实例化是创建对象,相当于new这个操作符;而依赖注入是注入对象方法的参数或对象的属性(可以理解成给它们赋值)。

其实我们在介绍实例化bean(http://blog.csdn.net/shymi1991/article/details/48153293) 的时候,除了空构造器的例子,其他例子已经涉及到了依赖注入,只是这里注入的是java基本类型,用的是基于构造器的注入方法

下面详细介绍两种注入方法

一、构造器注入:

调用带参构造器来实现(静态工场方法的参数也可以看做是这一类型),这种方法bean的实例化和依赖注入是同时进行的。

可以根据构造器参数的 索引、类型和名称来注入。


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

根据索引 index
<bean id="exampleBean" class="examples.ExampleBean">
  <constructor-arg index="0" value="7500000"/>
  <constructor-arg index="1" value="42"/>
</bean>

根据类型 type
<bean id="exampleBean" class="examples.ExampleBean">
  <constructor-arg type="int" value="7500000"/>
  <constructor-arg type="java.lang.String" value="42"/>
</bean>

根据名称name
<bean id="exampleBean" class="examples.ExampleBean">
  <constructor-arg name="years" value="7500000"/>
  <constructor-arg name="ultimateAnswer" value="42"/>
</bean>

上例注入的是常量,注入的参数也可以是其他类型,如 引用(其他的bean)。

例子:

package x.y;

public class Foo {
    public Foo(Bar bar,Baz baz) {
        // ...
    }
}

   
	 <bean id="barBean" class="x.y.Bar"></bean>
	 <bean id="bazBean" class="x.y.Baz"></bean>
	 <bean name="foo" class="x.y.Foo">
	     <constructor-arg ref="barBean"/>
	     <constructor-arg ref="bazBean"/>
	 </bean>
 


二、setter注入:

通过setter方法的参数实现,其实配置跟基于构造器的差不多,属性是property。

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="anotherExampleBean" class="examples.AnotherBean"/>
<bean id="yetAnotherBean" class="examples.YetAnotherBean"/>      
<bean id="exampleBean" class="examples.ExampleBean">

  <!-- 使用内嵌的 <ref/> 元素 -->
  <property name="beanOne">
  	<ref bean="anotherExampleBean"/>
  </property>

  <!-- 使用ref属性 -->
  <property name="beanTwo" ref="yetAnotherBean"/>
  <property name="integerProperty" value="1"/>
</bean>

其实基于constructor和基于setter的参数注入 最终效果是一样的,那么在实际运用中选择哪种方式呢?Spring小组建议用setter,因为过多的参数会显得constructor很笨重;而且基于setter的参数配置利于后续修改。但有的Purists更倾向于用基于constructor,因为它在初始化的过程中就一并注入参数。


注:<property />和<constructor-arg />的很多属性都有其对应的内嵌元素,两种格式的效果是一样的,可看做是全写和简写。下面是不同参数类型的注入全写和简写:

1)常量值(基础类型、String)

写:<property name="message" value="常量"/>

全写:<property name="message"><value>常量</value></property>

2)引用

写:<property name="message" ref="引用"/>

全写:<property name="message"><ref bean="引用"/></property>

3)数组:<array>没有简写形式

4)列表:<list>没有简写形式

5)集合:<set>没有简写形式

6)字典

简写:<map>

<entry key="键常量" value="值常量"/>

<entry key-ref="键引用"value-ref="值引用"/>

</map>

全写:<map>

<entry><key><value>键常量</value></key><value>值常量</value></entry>

<entry><key><refbean="键引用"/></key><ref bean="值引用"/></entry>

</map>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读