Spring之IOC容器注入

上一篇做了IOC和AOP的原理介绍,这一篇主要讲解IOC的注入。不过我依然困惑一个问题:

一 : 依赖注入(DI)中有三种注入方式,那Spring中到底实现了几种方式?也是三种?

IOC在很多框架中都有实现,并不是Spring特有的,之前说过IOC主要包含DL(Dependency Lookup)和DI(Dependency Injection),也就是说实现IOC的技术有很多,但是主要包含DI和DL,但是相对而言,DI应用范围比较广泛,我想这也是为什么Martin Fowler将控制反转用依赖注入来代替的原因;在具体的应用中DI主要实现了接口注入(Type1 IOC),setter注入(Type2 IOC),构造器注入(Type3 IOC)这三种方式,在Spring的IOC设计中,实现了设值注入和构造注入,也是最主要的注入方式(也就是说Spring中还有其它注入方式),貌似目前并没有实现接口注入这一方法,但是在另一框架Avalon却实现了。

也就是说:1.依赖注入(DI)有三种注入方式:接口注入(Type1 IOC),设值注入(Type2 IOC),构造注入(Type3 IOC)

                    2.在Spring中IOC主要是DI实现,DI实现了设值注入和构造注入,但是Spring的IOC中除了依赖注入方式,还有其它注入方式。

                    3.所有javaEE框架的IOC实现,主要是上是基于DI的接口注入(Type1 IOC),setter注入(Type2 IOC),构造器注入(Type3 IOC)这三种方式实现


那么既然Spring中IOC主要用设值注入和构造注入实现,就先实现这两种:

          设值注入(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"/>


 
package examples;
public class ExampleBean {
	private AnotherBean beanOne; //第一个java bean
	private YetAnotherBean beanTwo;// 第二个java bean
	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="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"/>


 

package examples;
public class ExampleBean {
	private AnotherBean beanOne; //第一个java bean
	private YetAnotherBean beanTwo;// 第二个java bean
	private int i;// 一个整形变量
	
	public ExampleBean(
	        AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {
	        this.beanOne = anotherBean;
	        this.beanTwo = yetAnotherBean;
	        this.i = i;
	    }
}

除了这两种以外,还可以使用静态工厂方法和实例工厂方法进行注入

静态工厂方法:

-----------我们除了使用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;
    }
}

实例工厂方法:

<!-- 使用实例工厂方法实例化 -->
<bean id="exampleBean" factory-bean="instanceFactory"
factory-method="createInstance">
<constructor-arg ref="anotherExampleBean"/>
<constructor-arg ref="yetAnotherBean"/>
<constructor-arg value="1">
</bean>

<bean id="instanceFactory" class="examples.exampleBean"/>
<bean id="anotherExampleBean" class="examples.AnotherBean"/>
<bean id="yetAnotherBean" class="examples.YetAnotherBean"/>

public class ExampleBean {

    // a private constructor
    private ExampleBean(...) {
      ...
    }
    
    public ExampleBean createInstance (
            AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {

        ExampleBean eb = new ExampleBean (...);
        // some other operations...
        return eb;
    }
}
请注意,传给 静态工厂方法的参数由 constructor-arg元素提供,这与使用构造器注入时完全一样。而且,重要的是,工厂方法所返回的实例的类型并不一定要与包含 static工厂方法的类类型一致。尽管在此例子中它的确是这样。非静态的实例工厂方法与此相同(除了使用 factory-bean属性替代 class属性外)。

参考资料:《Spring技术内幕》,《Dependency Injection》

Spring官方手册:http://docs.spring.io/spring/docs/

欢迎共同探讨Spring技术,后面有时间会继续更新,希望能够不断完善,出现的错误非常欢迎指正

      

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值