自动装备
1、定义
- 自动装配(autowiring): 将某个Bean实例中所引用的其它的Bean自动注入到当前Bean实例中
- 自动装配就是指由Spring来自动地注入依赖对象,无需人工参与。
- 自动装配的好处是减少构造器注入和setter注入配置,减少配置文件的长度。自动装配通过配置<bean>标签的 “autowire”属性来改变自动装配方式。
2、四种装配方式
- no(default): 默认值,即不启动自动装配,需要显示地引用相应的bean
setter 注入 : ( setter-base ),提供setter方法进行注入,依赖于无参构造和setter方法
Person类
package ecut.ioc.autowiring; public class Person { private Integer id; private String name; private Dog wangcai ; public Person() { super(); } public Person(Dog wangcai) { super(); this.wangcai = wangcai; System.out.println( "public Person(Dog)" ); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Dog getWangcai() { return wangcai; } public void setWangcai(Dog wangcai) { this.wangcai = wangcai; } }
Dog类
package ecut.ioc.autowiring; public class Dog { private String name ; public String getName() { return name; } public void setName(String name) { this.name = name; } }
配置文件
<bean id="dog" class="ecut.ioc.autowiring.Dog" > <property name="name" value="拉的多不多" /> </bean> <bean id="p" class="ecut.ioc.autowiring.Person" > <property name="id" value="1001" /> <property name="name" value="华安" /> <property name="wangcai" ref="dog" /> </bean>
构造方法注入 : ( constructor-base )通过构造方法往里面传入值
配置文件
<bean id="dog" class="ecut.ioc.autowiring.Dog" > <property name="name" value="拉的多不多" /> </bean> <bean id="p" class="ecut.ioc.autowiring.Person" > <property name="id" value="1001" /> <property name="name" value="华安" /> <constructor-arg name="wangcai" ref="dog" /> </bean>
- byName: 根据属性名称和被引用的bean名称来实现自动注入(setter)
byName-autowiring.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-4.3.xsd"> <bean id="dog" class="ecut.ioc.autowiring.Dog" > <property name="name" value="拉的多不多" /> </bean> <bean id="wangcai" class="ecut.ioc.autowiring.Dog" > <property name="name" value="旺财" /> </bean> <!-- 根据 名称 实现 自动装配 ( setter ) --> <bean id="huaan" class="ecut.ioc.autowiring.Person" autowire="byName" > <property name="id" value="1001" /> <property name="name" value="华安" /> <!-- <property name="wangcai" ref="wangcai" /> --> </bean> </beans>
如果在被装配的bean中含有xxx属性(实际上是setter方法),则会自动把id为xxx的bean装配上来
测试类package ecut.ioc.autowiring; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AutowireByName { public static void main(String[] args) { String configLocations = "classpath:ecut/**/byName-autowiring.xml" ; AbstractApplicationContext container = new ClassPathXmlApplicationContext( configLocations ); Person s = container.getBean( "huaan" , Person.class ); System.out.println( s.getId() + " : " + s.getName() ); Dog d = s.getWangcai(); System.out.println( d.getName() ); container.close(); } }
- byType: 根据属性类型和被引用的bean的类型来实现自动注入(setter)
byType-autowiring.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-4.3.xsd"> <!-- NoUniqueBeanDefinitionException <bean id="dog" class="ecut.ioc.autowiring.Dog" > <property name="name" value="拉的多不多" /> </bean> --> <bean id="wangcai" class="ecut.ioc.autowiring.Dog" > <property name="name" value="旺财" /> </bean> <!-- 根据 类型 实现 自动装配 ( setter ) --> <bean id="huaan" class="ecut.ioc.autowiring.Person" autowire="byType" > <property name="id" value="1001" /> <property name="name" value="华安" /> </bean> </beans>
如果在被装配的bean中含有一个xxx类型的属性,则会自动把类型为xxx的bean装配上来,但是如果含有多个xxx类型的bean,则抛出NoUniqueBeanDefinitionException
测试案例package ecut.ioc.autowiring; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AutowireByType { public static void main(String[] args) { String configLocations = "classpath:ecut/**/byType-autowiring.xml" ; AbstractApplicationContext container = new ClassPathXmlApplicationContext( configLocations ); Person s = container.getBean( "huaan" , Person.class ); System.out.println( s.getId() + " : " + s.getName() ); Dog d = s.getWangcai(); System.out.println( d.getName() ); container.close(); } }
- constructor: 根据构造方法的参数类型和被引用的Bean的类型实现自动装配(constructor)
当存在多个同种类型的Bean与构造方法中的参数类型相同时:
如果某Bean的名称跟参数的名称一致,则根据名称进行自动装配。constructor-autowiring.xml中bean的名称和构造方法中 public Person(Dog wangcai) 的参数保持一致。下面配置输出狗的名称是旺财<?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-4.3.xsd"> <bean id="dog" class="ecut.ioc.autowiring.Dog" > <property name="name" value="拉的多不多" /> </bean> <bean id="wangcai" class="ecut.ioc.autowiring.Dog" > <property name="name" value="旺财" /> </bean> <!-- 根据 类型 实现 自动装配 ( constructor ) --> <bean id="huaan" class="ecut.ioc.autowiring.Person" autowire="constructor" > <property name="id" value="1001" /> <property name="name" value="华安" /> </bean> </beans>
如果这些Bean的名称跟参数的名称都不相同,则不再执行自动装配。但是,也不抛出异常
<?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-4.3.xsd"> <bean id="dog" class="ecut.ioc.autowiring.Dog" > <property name="name" value="拉的多不多" /> </bean> <bean id="wc" class="ecut.ioc.autowiring.Dog" > <property name="name" value="旺财" /> </bean> <!-- 根据 类型 实现 自动装配 ( constructor ) --> <bean id="huaan" class="ecut.ioc.autowiring.Person" autowire="constructor" > <property name="id" value="1001" /> <property name="name" value="华安" /> </bean> </beans>
当且仅当与构造方法中的参数类型相同的Bean只有一个时,此时根据类型进行自动装配。下面配置输出狗的名称是拉的多不多
<?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-4.3.xsd"> <bean id="dog" class="ecut.ioc.autowiring.Dog" > <property name="name" value="拉的多不多" /> </bean> <!-- 根据 类型 实现 自动装配 ( constructor ) --> <bean id="huaan" class="ecut.ioc.autowiring.Person" autowire="constructor" > <property name="id" value="1001" /> <property name="name" value="华安" /> </bean> </beans>
测试类
package ecut.ioc.autowiring; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AutowireByConstructor { public static void main(String[] args) { String configLocations = "classpath:ecut/**/constructor-autowiring.xml" ; AbstractApplicationContext container = new ClassPathXmlApplicationContext( configLocations ); Person s = container.getBean( "huaan" , Person.class ); System.out.println( s.getId() + " : " + s.getName() ); Dog d = s.getWangcai(); System.out.println( d.getName() ); container.close(); } }
使用构造方法自动装备,创建person实例时,使用带参数的构造,并为参数注入指定类型的bean。
加载配置文件通配符
1、* 匹配同一级别路劲的多个字符,ecut/*/autowiring/constructor-autowiring.xml
2、 ** 匹配多级路劲中的多个字符,ecut/**/constructor-autowiring.xml
String configLocations = "classpath:ecut/**/constructor-autowiring.xml" ;
AbstractApplicationContext container = new ClassPathXmlApplicationContext( configLocations );
ecut.ioc.autowiring包中有一个constructor-autowiring.xml
3、 ?仅匹配一个字符
4、如果多个包中都beans.xml文件,并且期望全部加载它们,则可以写作classpath*:ecut/**/beans.xml
ecut包中有beans.xml, ecut.ex包中有beans.xml,ecut.xxx.yyyy包中有beans.xml
转载请于明显处标明出处