前面我们创建IOC容器的bean都是通过类构造器(无论是属性注入还是构造器注入方式)来创建bean实例的。
在spring IOC容器中还提供了通过工厂来创建bean的方法。其中分为两种方式:静态工厂和实例工厂
静态工厂方法创建 Bean
调用静态工厂方法创建 Bean是将对象创建的过程封装到静态方法中. 当客户端需要对象时, 只需要简单地调用静态方法, 而不同关心创建对象的细节.
要声明通过静态方法创建的 Bean, 需要在 Bean 的 class 属性里指定拥有该工厂的方法的类, 同时在 factory-method 属性里指定工厂方法的名称. 最后, 使用 <constrctor-arg> 元素为该方法传递方法参数.
实例工厂方法创建 Bean
实例工厂方法: 将对象的创建过程封装到另外一个对象实例的方法里. 当客户端需要请求对象时, 只需要简单的调用该实例方法而不需要关心对象的创建细节.
要声明通过实例工厂方法创建的 Bean
在 bean 的 factory-bean 属性里指定拥有该工厂方法的 Bean
在 factory-method 属性里指定该工厂方法的名称
使用 construtor-arg 元素为工厂方法传递方法参数
我们还是用例子说话吧:
显示bean类的定义:
package com.happyBKs.factory;
public class CarBean {
String brand;
double price;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public CarBean(String brand, double price) {
super();
this.brand = brand;
this.price = price;
}
public CarBean() {
super();
System.out.println(this.brand+" Constructor ....");
}
@Override
public String toString() {
return "CarBean [brand=" + brand + ", price=" + price + "]";
}
}
容器配置文件beans-factory.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.xsd">
<!-- 通过静态工厂方法来配置bean:注意不是配置静态工厂的实例,而是配置bean实例 -->
<!--
class属性:指向静态工厂长方法的全类名
factory-method 属性:指向静态工厂方法的名字
constructor-arg:如果工厂方法需要传入参数,则使用constructor-arg类配置参数
-->
<bean id="car1" class="com.happyBKs.factory.CarStaticFactory"
factory-method="getCar">
<constructor-arg value="VOLVONO1"></constructor-arg>
</bean>
<!-- 通过实体工厂的方法来配置bean (需要工厂单独配置一个实例) -->
<!-- 配置工厂的实例 -->
<bean id="carFactoryBean" class="com.happyBKs.factory.CarInstanceFactory" />
<!-- 通过工厂实例方法来配置bean -->
<!--
factory-bean属性:指向实例工厂 方法的全类名
factory-method属性:指向实例工厂方法的名字
constructor-arg:如果工厂方法需要传入参数,则使用constructor-arg类配置参数
-->
<bean id="car2" factory-bean="carFactoryBean" factory-method="getCar">
<constructor-arg value="VOLVONO1"></constructor-arg>
</bean>
</beans>
注意:静态工厂直接在bean本身的class注明即可,而实例工厂则需要先为实例工厂配置一个bean,然后将这个工厂bean在相应bean的factory-bean中指出。
测试代码:
package com.happBKs.spring.iocaop;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.happyBKs.factory.CarBean;
public class TestFactory {
@Test
public void testStaticFactory()
{
AbstractApplicationContext ac=new ClassPathXmlApplicationContext("beans-factory.xml");
CarBean cb=(CarBean)ac.getBean("car1");
System.out.println(cb);
ac.close();
}
@Test
public void testInstanceFactory()
{
AbstractApplicationContext ac=new ClassPathXmlApplicationContext("beans-factory.xml");
CarBean cb=(CarBean)ac.getBean("car2");
System.out.println(cb);
ac.close();
}
}
输出结果都是:
CarBean [brand=volvo S60L, price=600000.0]
下面我们通过例子来说明: