平常的Java開發中,程序員在某個類中需要依賴其它類的方法。
通常是new一個依賴類再調用類實例的方法,這種開發存在的問題是new的類實例不好統一管理。
Spring提出了依賴注入的思想,即依賴類不由程序員實例化,而是通過Spring容器幫我們new指定實例並且將實例注入到需要該對象的類中。
依賴注入的另一種說法是"控制反轉"。通俗的理解是:平常我們new一個實例,這個實例的控制權是我們程序員。
而控制反轉是指new實例工作不由我們程序員來做而是交給Spring容器來做。
1.Set注入
構建一個Student對象
package cn.happy.entity; /** * Created by CKW on 2017/3/19. */ public class Student { private String sname; private Integer sage; public Integer getSage() { return sage; } public void setSage(Integer sage) { this.sage = sage; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } }
在配置applicationContext.xml中:
<!--set 注入 prototype 原型 singletion 單例--> <bean id="stu" class="cn.happy.entity.Student" scope="prototype"> <property name="sname" value="張三"></property> <property name="sage" value="11"></property> </bean>
測試類中:
//被Spring管理的bean默認都是單例的 @Test public void myTest1(){ //ac 就是Spring容器 ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); Student stu=(Student) ac.getBean("stu"); Student stu1=(Student) ac.getBean("stu"); System.out.println(stu+"\n"+stu1); }
2.構造器注入
在對象中添加構造
配置中:
<!--構造注入--> <bean id="car1" class="cn.happy.entity.Car"> <property name="cname" value="圖驢子"></property> </bean> <bean id="stu1" class="cn.happy.entity.Student"> <!--(2)創建構造器注入,如果主類有帶參的構造方法則需添加此配置--> <constructor-arg index="0" value="哇哈哈"></constructor-arg> <constructor-arg index="1" value="11"></constructor-arg> <constructor-arg index="2" ref="car1"></constructor-arg> </bean>
測試類:
//構造注入 @Test public void myTest2(){ ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); Student stu1=(Student) ac.getBean("stu1"); Student stu2=(Student) ac.getBean("stu2"); System.out.println("構造:"+stu1); }
3.空間命名注入
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd ">
<!--命名空間P注入--> <bean id="car2" class="cn.happy.entity.Car"> <property name="cname" value="毛驢"></property> </bean> <bean id="stu2" class="cn.happy.entity.Student" p:sname="李四" p:sage="18" p:car-ref="car2"></bean>
//構造注入 命名空間注入 @Test public void myTest2(){ ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); Student stu1=(Student) ac.getBean("stu1"); Student stu2=(Student) ac.getBean("stu2"); System.out.println("構造:"+stu1+"\n命名空間:"+stu2); }
4.集合注入
<!--list集合屬性注入--> <bean id="collection1" class="cn.happy.entity.MyCollection"> <property name="list"> <list> <value>哈哈</value> <value>呵呵</value> <value>嘿嘿</value> </list> </property> </bean> <!--set集合屬性注入--> <bean id="collection2" class="cn.happy.entity.MyCollection"> <property name="set"> <set> <value>哈哈</value> <value>呵呵</value> <value>嘿嘿</value> </set> </property> </bean> <!--Map集合屬性注入--> <bean id="collection3" class="cn.happy.entity.MyCollection"> <property name="map"> <map> <entry key="001"> <value>呵呵</value> </entry> <entry key="002"> <value>哈哈</value> </entry> <entry key="003"> <value>嘿嘿</value> </entry> </map> </property> </bean>
5.注解注入
package cn.happy.entity; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service; /** * Created by CKW on 2017/3/22. */ @Component("car") //不分層 /*@Repository //dao層*/ /*@Service //biz層*/ /*@Controller //action層*/ public class Car { @Value("特斯拉") private String cname; @Override public String toString() { return getCname(); } public Car() { } public Car(String cname) { this.cname = cname; } public String getCname() { return cname; } public void setCname(String cname) { this.cname = cname; } }
package cn.happy.entity; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.Resource; /** * Created by CKW on 2017/3/22. */ @Component("student") public class Student { @Value("撒打發") private String sname; @Value("20") private Integer sage; //jdk注解 // @Resource @Autowired @Qualifier("car") private Car car; @Override public String toString() { return "name="+getSname()+",age="+getSage()+",car="+getCar(); } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } public Student() { } public String getSname() { return sname; } public Student(String sname, Integer sage, Car car) { this.sname = sname; this.sage = sage; this.car = car; } public void setSname(String sname) { this.sname = sname; } public Integer getSage() { return sage; } public void setSage(Integer sage) { this.sage = sage; } }
在配置applicationContext.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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd ">
<!--注解--> <!--配置包掃描器--> <context:component-scan base-package="cn.happy.entity"></context:component-scan>
測試類:
//注解 @Test public void myTest4(){ ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); Student stu=(Student)ac.getBean("student"); System.out.println(stu.getCar().getCname()); }