首页 > 代码库 > Spring点滴七:Spring中依赖注入(Dependency Injection:DI)

Spring点滴七:Spring中依赖注入(Dependency Injection:DI)

    Spring机制中主要有两种依赖注入:Constructor-based Dependency Injection(基于构造方法依赖注入) 和 Setter-based Dependency Injection(基于Setter方法依赖注入)

一、Contructor-based Dependency Injection(基于构造方法注入)

  在bean标签中通过使用<constructor-arg />标签来实现

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="a" class="com.test.spring.A">
<!-- 引用其它bean两种不同实现--> <constructor-arg> <ref bean="b"/> </constructor-arg> <constructor-arg ref="c"/> <constructor-arg name="name" value="http://www.mamicode.com/张三"/> </bean> <bean id="b" class="com.test.spring.B"> </bean> <bean id="c" class="com.test.spring.C"> </bean> </beans>

Java 类:

package com.test.spring;

public class A {

    private B b;
    private C c;
    private String name;
   
    public A(B b, C c, String name) {
        this.b = b;
        this.c = c;
        this.name = name;
    }

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }

    public C getC() {
        return c;
    }

    public void setC(C c) {
        this.c = c;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "A [b=" + b + ", c=" + c + ", name=" + name + "]";
    }
    
}
-------------------------------------------------------------------------------------------------------------------------------------------------
package com.test.spring;

public class B {
   
}
-------------------------------------------------------------------------------------------------------------------------------------------------
package com.test.spring;

public class C {

}

测试:

package com.test.spring;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class T {
    AbstractApplicationContext applicationcontext=null;
    @Before
    public void before() {
        System.out.println("》》》Spring ApplicationContext容器开始初始化了......");
        applicationcontext= new ClassPathXmlApplicationContext(new String[]{"test1-service.xml"});
        System.out.println("》》》Spring ApplicationContext容器初始化完毕了......");
    }
    @Test
    public void  test() {
        A a=applicationcontext.getBean(A.class);
        System.out.println(a);
    }
}

测试结果:

》》》Spring ApplicationContext容器开始初始化了......
2017-03-19 14:02:53  INFO:ClassPathXmlApplicationContext-Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@18c92ff9: startup date [Sun Mar 19 14:02:53 CST 2017]; root of context hierarchy
2017-03-19 14:02:53  INFO:XmlBeanDefinitionReader-Loading XML bean definitions from class path resource [test1-service.xml]
》》》Spring ApplicationContext容器初始化完毕了......
A [b=com.test.spring.B@4899c2aa, c=com.test.spring.C@66bb4c22, name=张三]

Spring 官网API提供够了使用静态工厂方法来实现上述功能:

Spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">    
   
   <bean id="a" class="com.test.spring.A" factory-method="getInstence">
       <constructor-arg>
          <ref bean="b"/>
       </constructor-arg>
       <constructor-arg ref="c"/>
       <constructor-arg name="name" value="http://www.mamicode.com/张三"/>
    </bean>
    <bean id="b" class="com.test.spring.B">
    </bean>
    <bean id="c" class="com.test.spring.C">
    </bean>
</beans>

Java类:

package com.test.spring;


public class A {

    private B b;
    private C c;
    private String name;
    /**
     * 创建一个私有的构造方法
     * @param b
     * @param c
     * @param name
     */
    private A(B b, C c, String name) {
        this.b = b;
        this.c = c;
        this.name = name;
    }
    
    public static A getInstence(B b,C c,String name){
        System.out.println("调用了静态的工厂方法");
        A a = new A(b,c,name);
        return a;
    }

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }

    public C getC() {
        return c;
    }

    public void setC(C c) {
        this.c = c;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "A [b=" + b + ", c=" + c + ", name=" + name + "]";
    }
    
}
--------------------------------------------------------------------------------
B.java C.java(略)

测试:

package com.test.spring;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class T {
    AbstractApplicationContext applicationcontext=null;
    @Before
    public void before() {
        System.out.println("》》》Spring ApplicationContext容器开始初始化了......");
        applicationcontext= new ClassPathXmlApplicationContext(new String[]{"test1-service.xml"});
        System.out.println("》》》Spring ApplicationContext容器初始化完毕了......");
    }
    @Test
    public void  test() {
        A a=applicationcontext.getBean(A.class);
        A a2=applicationcontext.getBean(A.class);
        System.out.println(a==a2);//发现A的实例对象是单例的
        System.out.println(a);
        System.out.println(a2);
    }
}

测试结果:

》》》Spring ApplicationContext容器开始初始化了......
2017-03-19 14:22:31  INFO:ClassPathXmlApplicationContext-Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@17ad352e: startup date [Sun Mar 19 14:22:31 CST 2017]; root of context hierarchy
2017-03-19 14:22:31  INFO:XmlBeanDefinitionReader-Loading XML bean definitions from class path resource [test1-service.xml]
调用了静态的工厂方法
》》》Spring ApplicationContext容器初始化完毕了......
true
A [b=com.test.spring.B@176730bb, c=com.test.spring.C@77b050fd, name=张三]
A [b=com.test.spring.B@176730bb, c=com.test.spring.C@77b050fd, name=张三]

2.Setter-based Dependency Injection(基于Setter方式依赖注入):该注入方式是经常使用的

spring.xml

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
   <bean id="a" class="com.test.spring.A">
       <property name="b" ref="b"/>
       <property name="c" ref="c"/>
       <property name="name" value="http://www.mamicode.com/张三"/>
    </bean>
    <bean id="b" class="com.test.spring.B">
    </bean>
    <bean id="c" class="com.test.spring.C">
    </bean>
</beans>

Java类:

package com.test.spring;


public class A {

    private B b;
    private C c;
    private String name;

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }

    public C getC() {
        return c;
    }

    public void setC(C c) {
        this.c = c;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "A [b=" + b + ", c=" + c + ", name=" + name + "]";
    }
    
}

测试:

package com.test.spring;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class T {
    AbstractApplicationContext applicationcontext=null;
    @Before
    public void before() {
        System.out.println("》》》Spring ApplicationContext容器开始初始化了......");
        applicationcontext= new ClassPathXmlApplicationContext(new String[]{"test1-service.xml"});
        System.out.println("》》》Spring ApplicationContext容器初始化完毕了......");
    }
    @Test
    public void  test() {
        //BeanLifecycle beanLifecycle =applicationcontext.getBean("beanLifecycle",BeanLifecycle.class);
        //applicationcontext.close();
        //applicationcontext.registerShutdownHook();  
        A a=applicationcontext.getBean(A.class);
        System.out.println(a);
    }
}

测试结果:

》》》Spring ApplicationContext容器开始初始化了......
2017-03-19 14:34:20  INFO:ClassPathXmlApplicationContext-Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@17ad352e: startup date [Sun Mar 19 14:34:20 CST 2017]; root of context hierarchy
2017-03-19 14:34:20  INFO:XmlBeanDefinitionReader-Loading XML bean definitions from class path resource [test1-service.xml]
》》》Spring ApplicationContext容器初始化完毕了......
A [b=com.test.spring.B@49daafb9, c=com.test.spring.C@3446c090, name=张三]

这两种注入方式在Spring配置文件中可以一起使用

Spring点滴七:Spring中依赖注入(Dependency Injection:DI)