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配置文件中可以一起使用