静态工厂
首先,要有一个静态工厂来生成对象,编写一个Car类和一个StaticCarFactory类:
package cn.net.bysoft.lesson5;
public class Car {
public Car() {
}
public Car(String name) {
this.name = name;
}
@Override
public String toString() {
return "Car [name=" + name + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private String name;
}
package cn.net.bysoft.lesson5;
import java.util.HashMap;
import java.util.Map;
public class StaticCarFactory {
private static Map<String, Car> cars = new HashMap<String, Car>();
static {
cars.put("Audi", new Car("Audi"));
cars.put("Ford", new Car("Ford"));
}
public static Car getCar(String name) {
return cars.get(name);
}
}
在spring的配置文件进行配置,让spring帮我们调用静态工厂方法生成Car对象:
<bean id="car1" class="cn.net.bysoft.lesson5.StaticCarFactory"
factory-method="getCar">
<constructor-arg value="Audi"></constructor-arg>
</bean>
可以看到class不在是Car的全类名,而是静态工厂的全类名,factory-method属性指向的是工厂中生成Car的方法名称,而这个方法有一个name参数,我们通过constructor-arg元素进行传参,传送给静态工厂方法一个Audi参数,要求工厂返回一个Car,名字是Audi,测试一下:
@Test
public void testStaticFactory() {
Car car1 = (Car) ctx.getBean("car1");
System.out.println(car1);
/**
* output:Car [name=Audi]
* */
}
实例工厂
其实与静态工厂的用法类似,创建一个实例工厂:
package cn.net.bysoft.lesson5;
import java.util.HashMap;
import java.util.Map;
public class InstanceCarFactory {
private Map<String, Car> cars = new HashMap<String, Car>();
public InstanceCarFactory() {
cars.put("Audi", new Car("Audi"));
cars.put("Ford", new Car("Ford"));
}
public Car getCar(String name) {
return cars.get(name);
}
}
修改一个配置文件:
<bean id="carFactory" class="cn.net.bysoft.lesson5.InstanceCarFactory"></bean>
<bean id="car2" factory-bean="carFactory" factory-method="getCar">
<constructor-arg value="Ford"></constructor-arg>
</bean>
首先,在配置文件中定义一个实例工厂的bean,接着,Car对象的bean不需要指定class了,而是使用factory-bean属性将实例工厂bean的id赋值到该属性,在定义factory-method,也就是生成对象的方法名称,给方法传值与之前的静态工厂一样。要求工厂生成一个Ford汽车,测试一下结果:
@Test
public void testInstanceFactory() {
Car car2 = (Car) ctx.getBean("car2");
System.out.println(car2);
/**
* output:Car [name=Ford]
* */
}
内置的FactoryBean
Spring为我们提供了一个FactoryBean接口,我们可以自定义工厂去实现这个接口:
package cn.net.bysoft.lesson5;
import org.springframework.beans.factory.FactoryBean;
public class CarFactoryBean implements FactoryBean<Car> {
private String brand;
public void setBrand(String brand) {
this.brand = brand;
}
@Override
public Car getObject() throws Exception {
// TODO Auto-generated method stub
return new Car(brand);
}
@Override
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return Car.class;
}
@Override
public boolean isSingleton() {
// TODO Auto-generated method stub
return true;
}
}
这个接口只有三个方法:getObject、getObjectType和isSingleton,分别用来获得一个对象、获得这个对象的类型和这个对象是否是单例的。
通过配置spring的配置文件,就可以使用这个工厂:
<bean id="car3" class="cn.net.bysoft.lesson5.CarFactoryBean">
<property name="brand" value="BMW"></property>
</bean>
将要生成的对象的class指定FactoryBean的全类名,设置属性,Spring会自动调用getObject()方法返回对象。
@Test
public void testFactoryBean() {
Car car3 = (Car) ctx.getBean("car3");
System.out.println(car3);
/**
* output:Car [name=BMW]
* */
}