Bean的装配
在xml文件当中,bean的装配分为手动装配和自动装配。其中手动装配主要是通过bean的set方法给bean对象注入属性值,而自动装配由xml文件中的”autowire“控制。
一 手动装配
手动装配没有什么需要特别注意的地方,主要是掌握配置集合属性的成员变量。
下面是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:context="http://www.springframework.org/schema/context"
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/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="department" class = "com.loadbean.Department">
<property name="departmentname" value= "财务部"/>
<property name="emp">
<list>
<value>1001</value>
<value>1002</value>
<value>1003</value>
</list>
</property>
<property name="empList">
<list>
<ref bean="employee1"/>
<ref bean="employee2"/>
<ref bean="employee1"/>
<ref bean="employee2"/>
<ref bean="employee1"/>
</list>
</property>
<property name="empSet">
<set>
<ref bean="employee2"/>
<ref bean="employee1"/>
<ref bean="employee1"/>
<ref bean="employee1"/>
</set>
</property>
<property name="empMap">
<map>
<entry key="001" value-ref="employee1"/>
<entry key="002" value-ref="employee2"/>
<entry key="003" value-ref="employee2"/>
</map>
</property>
</bean>
<bean id="employee1" class="com.loadbean.Employee">
<property name="empname">
<value>曾慧青</value>
</property>
<property name="empid" value="1001"/>
</bean>
<bean id="employee2" class = "com.loadbean.Employee">
<property name="empname" value="Vayne_Huang"/>
<property name="empid" value="1002"/>
</bean>
</beans>
下面是对应的Master类的成员变量:
private String departmentname;
private int[] emp;
private List<Employee> empList;
private Set<Employee> empSet;
private Map<Integer,Employee> empMap;
下面是测试类,应当注意的是map集合的遍历输出方法。
package com.loadbean;
import java.util.Map.Entry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App2 {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("com/loadbean/loadbean.xml");
Department dp = (Department)ac.getBean("department");
System.out.println(dp.getDepartmentname());
for(int e :dp.getEmp())
{
System.out.println(e);
}
System.out.println("******下面是雇员列表(List)********");
for(Employee e:dp.getEmpList())
{
System.out.println(e.getEmpid()+" "+e.getEmpname());
}
System.out.println("******下面是雇员列表(Set)********");
for(Employee e:dp.getEmpSet())
{
System.out.println(e.getEmpid()+" "+e.getEmpname());
}
System.out.println("******下面是雇员列表(Map)********");
for(Entry<Integer,Employee> e:dp.getEmpMap().entrySet())
{
System.out.println(e.getKey()+" "+e.getValue().getEmpid()+" "+e.getValue().getEmpname());
}
}
}
二 自动装配(autowire)
(1)五种基本方式。
自动装配主要有以下五种方式(来自Spring2.5文档):
下面来一示例代码:
<?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:context="http://www.springframework.org/schema/context"
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/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="master" class="com.hsp.autowire.Master" autowire="constructor">
<property name="name" value="青青" />
</bean>
<bean id="dog" class="com.hsp.autowire.Dog">
<property name="name" value="小U" />
<property name="age" value="3" />
</bean>
</beans>
其中 default设置的默认的自动装配方法,可以在beans标签当中指定,如果不指定,会默认为no。如果指定为byname,那么在bean标签中的default则为byname。
另外,set方式注入的属性值优于constructor设置的属性值,即如果通过set方式和自动装配的方式对bean实例的某一属性同时设置了值,那么以set方式设置的为准。
这里讲一下constructor,在上一篇Bean的生命周期当中,我们验证过,实例化一个bean的时候,会先调用其默认的无参构造方法,但是,如果我们配置自动装配的方式为constructor,那么在不抛出异常(详细条件见上表)且Bean的定义类中存在相应的构造器的情况下,会使用这有参构造器实例化bean。如果不存在有参的构造方法,那么才会使用无参构造方法实例化bean,以下是我作的验证:
首先是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:context="http://www.springframework.org/schema/context"
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/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="master" class="com.hsp.autowire.Master" autowire="constructor">
<property name="name" value="青青" />
</bean>
<bean id="dog" class="com.hsp.autowire.Dog">
<property name="name" value="小U" />
<property name="age" value="3" />
</bean>
</beans>
其次是我的Master类:
package com.hsp.autowire;
public class Master {
private String name;
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private Dog dog;
public Master()
{
System.out.println("这是无参构造方法");
}
public Master(Dog dog)
{
System.out.println("这是有参构造方法");
this.dog = dog;
}
public Master(Dog dog,String name)
{
this.dog = dog;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("Master的setName方法");
this.name = name;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
}
从这段JAVA代码中可以看到,如果执行无参方法,将会打印对应的话,如果执行有参,则会执行相应的打印语句。
下面是运行结果:
这是有参构造方法
Master的setName方法
小U
如果我们在xml配置中使用手动方式配置Master 的bean的dog属性,那么运行结果会变成:
这是有参构造方法
Master的setName方法
这是dog的set方法
小U
如果我们此时删除Master类中参数为dog的构造方法,那么运行结果:
这是无参构造方法
Master的setName方法
这是dog的set方法
小U
综上,可能看起来有点晕,但是我们要知道的是,实例化bean的时候,不一定会采用无参构造方法,也有可能采用有参构造方法。
(3)番外
在上篇bean的生命周期中我们讲到,如果配置的某个bean实现了某些接口,那么在实例bean对象的时候,就会以一定的顺序执行接口中的方法。那些bean就被称为spring的特殊bean。
分散配置
当同一值被多个bean的某个属性使用的时候(例如多个bean同时需要一个数据库驱动),那么在配置bean 的时候,需要多次输入这个值,毫无疑问这是很费时间和精力的。spring中提供了分散配置的方式来解决这个问题。
例如,我们将上例的Dog类的bean的名字属性放入gen.properties文件,然后在xml配置文件中使用它。
下面是gen.properties文件的内容。
name=xiaoU
然后我们在修改xml文件如下:
下面是运行结果:
这是无参构造方法
Master的setName方法
这是dog的set方法
xiaoU
我们可以看到,名字已经变为xiaoU。
以上如有错误,希望各位帮忙指正,谢谢。