IOC称之为控制反转,简单来说就是将对象 的创建的权力及对象的生命周期的管理过程交由Spring框架来处理,从此在开发过程中不在需要关注对象的创建和生命周期的管理,而是在需要的时候由Spring框架提供,这个由Spring框架管理对象创建和生命周期的机制称之为控制反转。而在创建对象的过程中Spring可以依据配置对象的属性进行设置,这个过程称之为依赖注入,也即DI
a. Spring内置可直接注入的类型
package cn.tedu.beans; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; public class Hero { private int id; private String name; private List<String> jobs; private Set<String> set; private Map<String,String> map; private Properties prop; private Dog dog; private Cat cat; public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; } public void setJobs(List<String> jobs) { this.jobs = jobs; } public void setSet(Set<String> set) { this.set = set; } public void setMap(Map<String, String> map) { this.map = map; } public void setProp(Properties prop) { this.prop = prop; } public void setDog(Dog dog) { this.dog = dog; } public void setCat(Cat cat) { this.cat = cat; } @Override public String toString() { return "Hero [id=" + id + ", name=" + name + ", jobs=" + jobs + ", set=" + set + ", map=" + map + ", prop=" + prop + ", dog=" + dog + ", cat=" + cat + "]"; } } <?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/springbeans3.2.xsd"> <bean id="hero" class="cn.tedu.beans.Hero"> <property name="id" value="123"></property> <property name="name" value="漂移崽"></property> <property name="jobs"> <list> <value>钢铁侠</value> <value>猪猪侠</value> <value>绿箭侠</value> <value>凹凸曼</value> </list> </property> <property name="set"> <set> <value>aaa</value> <value>bbb</value> <value>ccc</value> <value>aaa</value> </set> </property> <property name="map"> <map> <entry key="addr" value="王者荣耀"></entry> <entry key="addr" value="英雄联盟"></entry> <entry key="skill" value="风火轮"></entry> <entry key="age" value="19"></entry> </map> </property> <property name="prop"> <props> <prop key="kOne">v1</prop> <prop key="kTwo">v2</prop> <prop key="kThree">v3</prop> <prop key="kFour">v4</prop> </props> </property> </bean> </beans> /** * SpringDI set方式属性注入 - Spring内置的可直接注入类型的注入 */ @Test public void test1(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Hero hero = (Hero) context.getBean("hero"); System.out.println(hero); }b. 非Spring内置可直接注入的类型
package cn.tedu.beans; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; public class Hero { private int id; private String name; private List<String> jobs; private Set<String> set; private Map<String,String> map; private Properties prop; private Dog dog; private Cat cat; public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; } public void setJobs(List<String> jobs) { this.jobs = jobs; } public void setSet(Set<String> set) { this.set = set; } public void setMap(Map<String, String> map) { this.map = map; } public void setProp(Properties prop) { this.prop = prop; } public void setDog(Dog dog) { this.dog = dog; } public void setCat(Cat cat) { this.cat = cat; } @Override public String toString() { return "Hero [id=" + id + ", name=" + name + ", jobs=" + jobs + ", set=" + set + ", map=" + map + ", prop=" + prop + ", dog=" + dog + ", cat=" + cat + "]"; } } <?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/springbeans3.2.xsd"> <bean id="hero" class="cn.tedu.beans.Hero"> <property name="id" value="123"></property> <property name="name" value="亚瑟 "></property> <property name="jobs"> <list> <value>钢铁侠</value> <value>猪猪侠</value> <value>绿箭侠</value> <value>凹凸曼</value> </list> </property> <property name="set"> <set> <value>aaa</value> <value>bbb</value> <value>ccc</value> <value>aaa</value> </set> </property> <property name="map"> <map> <entry key="addr" value="王者荣耀"></entry> <entry key="addr" value="英雄联盟"></entry> <entry key="skill" value="风火轮"></entry> <entry key="age" value="19"></entry> </map> </property> <property name="prop"> <props> <prop key="kOne">v1</prop> <prop key="kTwo">v2</prop> <prop key="kThree">v3</prop> <prop key="kFour">v4</prop> </props> </property> <property name="dog" ref="dog"></property> <property name="cat" ref="cat"></property> </bean> <bean id="dog" class="cn.tedu.beans.Dog"></bean> <bean id="cat" class="cn.tedu.beans.Cat"></bean> </beans> /** * SpringDI set方式属性注入 - Spring内置的可直接注入类型的注入 */ @Test public void test2(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Hero hero = (Hero) context.getBean("hero"); System.out.println(hero); }在Spring的set方式实现的注入过程中,支持自动装配机制,所谓自动装配机制,会根据要设置的javabean属性的名字 或 类型 到spring中自动寻找对应id 或 类型的进行设置,从而 省去依次配置的过程,简化了配置。
a. 指定开始自动装配
<?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/springbeans3.2.xsd"> <!-- autowire设定自动装配: byName:根据javabean中需要注入的属性的名字 ,在spring容器中找对应id的<bean>将该<bean>的对象复制给 当前的属性 byType:根据javabean中需要注入的属性的类型,在spring容器中找对应class类型的<bean>将该<bean>的对象复制给 当前的属性 **byType方式 根据类型进行匹配,可能匹配到多个<bean>,此时会抛出异常。而byName是通过id来寻找<bean>,id没有重复,不会有这方面的问题,所以推荐使用byName方式 --> <bean id="teacher" class="cn.tedu.beans.Teacher" autowire="byName"></bean> <bean id="dog" class="cn.tedu.beans.Dog"></bean> <bean id="cat" class="cn.tedu.beans.Cat"></bean> </beans>b. 全局配置自动装配
<?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/springbeans3.2.xsd"default-autowire="byName"> <!-- autowire设定自动装配: byName:根据javabean中需要注入的属性的名字 ,在spring容器中找对应id的<bean>将该<bean>的对象复制给 当前的属性 byType:根据javabean中需要注入的属性的类型,在spring容器中找对应class类型的<bean>将该<bean>的对象复制给 当前的属性 **byType方式 根据类型进行匹配,可能匹配到多个<bean>,此时会抛出异常。而byName是通过id来寻找<bean>,id没有重复,不会有这方面的问题,所以推荐使用byName方式 --> <bean id="teacher" class="cn.tedu.beans.Teacher"></bean> <bean id="dog" class="cn.tedu.beans.Dog"></bean> <bean id="cat" class="cn.tedu.beans.Cat"></bean> </beans> package cn.tedu.beans; public class Teacher { private Dog dog; private Cat cat; public void setDog(Dog dog) { this.dog = dog; } public void setCat(Cat cat) { this.cat = cat; } @Override public String toString() { return "Teacher [dog=" + dog + ", cat=" + cat + "]"; } } /** * SpringDI 自动装配 */ @Test public void test4(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Teacher teacher = (Teacher) context.getBean("teacher"); System.out.println(teacher); }