Spring的核心机制:依赖注入

来源:互联网 发布:linux on android 编辑:程序博客网 时间:2024/06/06 14:25

1、设值注入:IoC容器使用属性的setter方法来注入被依赖的实例。

package DependencyInjection;public interface Person {public void useAxe();//定义一个使用斧头的方法}

package DependencyInjection;public interface Axe {public String chop();//Axe接口里有个砍的方法}

Person实现类

package DependencyInjection;public class Chinese implements Person {private Axe axe;public void setAxe(Axe axe) {//设值注入所需的setter方法this.axe = axe;}//实现Person接口useAxe方法public void useAxe() {System.out.println(axe.chop());}}

Axe实现类

package DependencyInjection;public class StoneAxe implements Axe {@Overridepublic String chop() {// TODO Auto-generated method stubreturn "石斧砍柴好慢";}}

package DependencyInjection;public class SteelAxe implements Axe {@Overridepublic String chop() {// TODO Auto-generated method stubreturn "钢斧砍柴真快";}}

配置文件

<?xml version="1.0" encoding="UTF-8"?><beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"><bean id="chinese" class="DependencyInjection.Chinese"><property name="axe" ref="stoneAxe"/></bean><bean id="stoneAxe" class="DependencyInjection.StoneAxe"/><bean id="steelAxe" class="DependencyInjection.SteelAxe"/></beans>

测试

package DependencyInjection;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanTest {public static void main(String[] args) {//创建Spring容器ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");//获取chinese实例Person p = ctx.getBean("chinese",Person.class);p.useAxe();}}

结果



2、构造注入:IoC容器使用构造器来注入被依赖的实例。

Person实现类

package DependencyInjection;public class Chinese implements Person {private Axe axe;public Chinese(){}//默认的构造器public Chinese(Axe axe){//构造注入所需的带参数的构造器this.axe=axe;}//实现Person接口useAxe方法public void useAxe() {System.out.println(axe.chop());}}

配置文件

<?xml version="1.0" encoding="UTF-8"?><beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"><bean id="chinese" class="DependencyInjection.Chinese"><constructor-arg ref="steelAxe"/></bean><bean id="stoneAxe" class="DependencyInjection.StoneAxe"/><bean id="steelAxe" class="DependencyInjection.SteelAxe"/></beans>

配置<constructor-arg.../>元素时可指定一个index属性,用于指定该构造参数值将作为第几个构造参数值,例如index="0"表明该构造参数值将作为第一个构造参数。


其他以及测试代码不变,运行结果:


执行效果与设值注入相同,区别在于:创建Person实例中Axe属性的时机不同——设值注入是先通过无参数的构造器创建一个Bean实例,然后调用对应的setter方法注入依赖关系;而构造注入则直接调用有参数的构造器,当Bean实例创建完成后,已经完成了依赖关系的注入。



对比

设值注入优点:与传统的JavaBean的写法更相似,更容易理解、接受。通过setter方法设定依赖关系显得更加直观、自然。

                         对于复杂的依赖关系,如果采用构造注入,会导致构造器过于臃肿,难以阅读。

构造注入优点:可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入。

                        对于依赖关系无须变化的Bean,构造注入更有用处。因为没有setter方法,所有的依赖关系全部在构造器内设定,因此。无须担心后续                  的代码对依赖关系产生破坏。

                        依赖关系只能在构造器中设定,则只有组件的创建者才能改变组件的依赖关系。对组建的调用者而言,组件内部的依赖关系完全透明,                  更符合高内聚的原则。


建议

      以设值注入为主,对于无须变化的Bean,尽量采用构造注入。


原创粉丝点击