1.什么是装配
创建应用对象之间的协作行为称之为装配。
以订单管理为例
a.调用仓储管理组件查询订单中的商品是否有库存
b.调用客户管理组件查询下单人是否存在,不存在则创建一个
c.调用结算组件计算订单金额
d.调用仓储管理组件出库。
以上过程说明一个订单管理组件是与其他组件之间相互协作才能完成一个订单处理功能。
spring的装配就是来创建这种对象间的协作行为的。
订单管理组件只需要定义一个其需要的组件的引用。并告诉spring我需要这些组件来协助我完成工作。那么在工作的时候,srping容器就会主动赋予一个该类型的组件给订单管理组件。
2.配置bean--配置文件方式
package com.amber.ivy.spring.bean;
/**
* @author ivyamber
* 工程师接口
*/
public interface Engineer {
/**
* 工程师都会做点什么
*/
void doSomeThing();
}
package com.amber.ivy.spring.bean;
/**
* 软件工程师
* @author ivyamber
*
*/
public class SoftwareEngineer implements Engineer{
private String language="C";
public SoftwareEngineer() {
// TODO Auto-generated constructor stub
}
public SoftwareEngineer(String language)
{
this.language = language;
}
@Override
public void doSomeThing() {
System.out.println("i am expert in"+language);
}
}
package com.amber.ivy.spring.bean;
/**
* 测试类
* @author ivyamber
*
*/
public class BeanTest {
private static Engineer e;
public static void main(String[] args) {
e.doSomeThing();
}
}
如果直接运行测试类,那么e肯定是一个空值。
使用spring配置文件去将e装配到测试类中。
配置文件
<?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-3.0.xsd">
<bean id="engineer" class="com.amber.ivy.spring.bean.SoftwareEngineer"/>
</beans>
说明1.xmlns指定命名空间,spring共有十个命名空间,每个命名空间里面有不同的标签,对应不同的功能。这里使用的是beans命名空间,支持声明bean和装配bean,是spring最核心的命名空间。
说明2.beans元素中可以嵌套多个bean元素,每个bean元素声明并实例化一个bean。id为该实例化的bean在容器中的标识,class是该bean的类型。spring将通过反射机制创建一个class类型的bean放到容器中。
重新编写测试类。
package com.amber.ivy.spring.bean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 测试类
* @author ivyamber
*
*/
public class BeanTest {
private static Engineer e;
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("com/amber/resource/bean.xml");
e = (Engineer) context.getBean("engineer");
e.doSomeThing();
}
}
打印:i am expert inC
这样有一个问题,无论何时软件工程师都只会用c语言,软件工程师的构造函数有一个带参数的。重写spring配置文件,使用带参数的构造函数去构造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-3.0.xsd">
<bean id="engineer" class="com.amber.ivy.spring.bean.SoftwareEngineer">
<constructor-arg value="java"/>
</bean>
</beans>
打印:i am expert injava
软件工程师如果会点才艺就好了。
package com.amber.ivy.spring.bean;
/**
* 表演家接口
* @author ivyamber
*
*/
public interface Performer {
void perform();
}
package com.amber.ivy.spring.bean;
/**
* 唱歌
* @author ivyamber
*
*/
public class Sing implements Performer{
@Override
public void perform() {
System.out.println("i am singing");
}
}
<?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-3.0.xsd">
<bean id="engineer" class="com.amber.ivy.spring.bean.SoftwareEngineer">
<constructor-arg value="java"/>
<constructor-arg ref="performer"/>
</bean>
<bean id="performer" class="com.amber.ivy.spring.bean.Sing"/>
</beans>
打印:i am expert injava
i am singing
spring装配bean的完整过程
3.使用setter方法装配bean
使用setter方法装配bean和使用构造函数装配bean本质上没有却别。不过假如需要配置的引用有十个。如果使用构造函数装配bean就要写一个有十个参数的构造函数,同事配置文件就要在bean中使用十个<constructor-arg/>子标签。
package com.amber.ivy.spring.bean;
/**
* 软件工程师
* @author ivyamber
*
*/
public class SoftwareEngineer implements Engineer{
private Performer p;
private String language="C";
public SoftwareEngineer() {
// TODO Auto-generated constructor stub
}
public SoftwareEngineer(String language)
{
this.language = language;
}
@Override
public void doSomeThing() {
System.out.println("i am expert in"+language);
//表演
p.perform();
}
public void setP(Performer p)
{
this.p = p;
}
}
在需要装配的bean中为属性添加set方法。
<?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-3.0.xsd">
<bean id="engineer" class="com.amber.ivy.spring.bean.SoftwareEngineer">
<constructor-arg value="java"/>
<property name = "p" ref="performer"/>
</bean>
<bean id="performer" class="com.amber.ivy.spring.bean.Sing" scope="prototype"/>
</beans>
为bean配置property标签