自动装配(autowire)协作者
Spring IoC容器可以自动装配(autowire)相互协作bean之间的关联关系。因此,如果可能的话,可以自动让Spring通过检查BeanFactory
中的内容,来替我们指定bean的协作者(其他被依赖的bean)。autowire一共有五种类型。由于autowire可以针对单个bean进行设置,因此可以让有些bean使用autowire,有些bean不采用。autowire的方便之处在减少或者消除属性或构造器参数的设置,这样可以给我们的配置文件减减肥!
no | |
byName | 根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配。例如,在bean定义中将autowire设置为by name,而该bean包含master属性(同时提供setMaster(..)方法),Spring就会查找名为 |
byType | 如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配。如果存在多个该类型的bean,那么将会抛出异常,并指出不能使用byType方式进行自动装配。若没有找到相匹配的bean,则什么事都不发生,属性也不会被设置。如果你不希望这样,那么可以通过设置 |
constructor | 与byType的方式类似,不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。 |
autodetect | 通过bean类的自省机制(introspection)来决定是使用constructor还是byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式。 |
示例:
我们可以看以下配置:
<bean id="bean2" class="com.lwf.bean.Bean2"> <property name="bean3" ref="bean3"/> <property name="bean4"> <ref bean="bean4"/> </property> <property name="bean5"> <bean id="bean5" class="com.lwf.bean.Bean5"> <property name="age" value="30"></property> </bean> </property> </bean>
<bean id="parentBean" abstract="true"> <property name="id" value="1"/> <property name="name" value="zhang"/> </bean> <bean id="bean3" class="com.lwf.bean.Bean3" parent="parentBean"> <property name="date" value="2010/05/19"/> </bean> <bean id="bean4" class="com.lwf.bean.Bean4" parent="parentBean"/>
我们可以看到bean2,bean3,bean4,bean5分别对应的类名为Bean2,Bean3,Bean4,Bean5
而Bean3,Bean4,Bean5分别为Bean2的成员属性,我们把成员属性的名字也定义为bean3,bean4,bean5即与配置文件中id的名字一致。
那么我们就可以使用自动装配来简化配置。
我们使用第一种:byName进行自动装配。在配置文件的beans标签增加属性:default-autowire="byName" 即可。
代码如下(本代码与前面一文中的使用bean继承相似):
package com.lwf.bean; public class Bean2 { private Bean3 bean3; private Bean4 bean4; private Bean5 bean5; public Bean3 getBean3() { return bean3; } public void setBean3(Bean3 bean3) { this.bean3 = bean3; } public Bean4 getBean4() { return bean4; } public void setBean4(Bean4 bean4) { this.bean4 = bean4; } public Bean5 getBean5() { return bean5; } public void setBean5(Bean5 bean5) { this.bean5 = bean5; } }
package com.lwf.bean; import java.util.Date; public class Bean3 { private int id; private String name; private Date date; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } }
package com.lwf.bean; public class Bean4 { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package com.lwf.bean; public class Bean5 { private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
两个配置文件:
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:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd" default-autowire="byName" > <bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer"> <property name="customEditors"> <map> <entry key="java.util.Date"> <bean class="com.lwf.bean.UtilDatePropertiesEditor"> <property name="format" value="yyyy/MM/dd"/> </bean> </entry> </map> </property> </bean> <!-- <bean id="bean2" class="com.lwf.bean.Bean2"> <property name="bean3" ref="bean3"/> <property name="bean4"> <ref bean="bean4"/> </property> <property name="bean5"> <bean id="bean5" class="com.lwf.bean.Bean5"> <property name="age" value="30"></property> </bean> </property> </bean> --> <bean id="bean2" class="com.lwf.bean.Bean2"/> <bean id="bean5" class="com.lwf.bean.Bean5"> <property name="age" value="33"></property> </bean> </beans>
applicationContext_1.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:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <bean id="parentBean" abstract="true"> <property name="id" value="1"/> <property name="name" value="zhang"/> </bean> <bean id="bean3" class="com.lwf.bean.Bean3" parent="parentBean"> <property name="date" value="2010/05/19"/> </bean> <bean id="bean4" class="com.lwf.bean.Bean4" parent="parentBean"/> </beans>
日期转换需要用到的类:
package com.lwf.bean; import java.beans.PropertyEditorSupport; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class UtilDatePropertiesEditor extends PropertyEditorSupport { private String format="yyyy/MM/dd" ; public void setAsText(String text) throws IllegalArgumentException { SimpleDateFormat sdf = new SimpleDateFormat(format); try { Date dateVal = sdf.parse(text); this.setValue(dateVal); } catch (ParseException e) { e.printStackTrace(); } } public void setFormat(String format){ this.format = format; } }
测试类:
package com.lwf.client; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.lwf.bean.Bean2; public class Client { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext*.xml"); Bean2 bean2 = (Bean2)ctx.getBean("bean2"); System.out.println(bean2.getBean3().getName()); System.out.println(bean2.getBean3().getId()); System.out.println(bean2.getBean3().getDate()); System.out.println(bean2.getBean4().getId()); System.out.println(bean2.getBean4().getName()); System.out.println(bean2.getBean5().getAge()); } }
输出结果:
2010-05-19 16:32:34,604 INFO [org.springframework.context.support.ClassPathXmlApplicationContext] - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3e86d0: display name [org.springframework.context.support.ClassPathXmlApplicationContext@3e86d0]; startup date [Wed May 19 16:32:34 CST 2010]; root of context hierarchy 2010-05-19 16:32:34,760 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - Loading XML bean definitions from file [D:\workdirlocal\spring_start\bin\applicationContext.xml] 2010-05-19 16:32:35,135 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - Loading XML bean definitions from file [D:\workdirlocal\spring_start\bin\applicationContext_1.xml] 2010-05-19 16:32:35,213 INFO [org.springframework.context.support.ClassPathXmlApplicationContext] - Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@3e86d0]: org.springframework.beans.factory.support.DefaultListableBeanFactory@1adc30 2010-05-19 16:32:35,369 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1adc30: defining beans [customEditorConfigurer,bean2,bean5,parentBean,bean3,bean4]; root of factory hierarchy zhang 1 Wed May 19 00:00:00 CST 2010 1 zhang 33
名称自动装配注意:
一、类中定义的成员属性与配置文件中的id名称一致;
二、在Beans标签增加default-autowire="byName"属性
自动装配缺点:日后修改比较麻烦,如果实现自动装配日后修改配置文件还需要到类里面一一查看属性名称。