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="张三"/> </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="张三"/> </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="张三"/> </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配置文件中可以一起使用