先说为什么会使用FactoryBean。
一般情况下,Spring通过反射机制利用bean的class属性指定实现类实例化Bean,在某些情况下,实例化Bean的过程比较复杂,按传统方式,则需要在 bean配置中提供大量配置信息。配置方式的灵活性受限的,这时采用编码的方式可能会获得一个简单的方案。Spring提供了一个org.springframework.beans.factory.FactoryBean工厂类接口,用户可以通过实现该工厂类接口定制实例化Bean的逻辑。
这个接口中定义了三个方法:
T getObject():返回由FactoryBean创建的Bean实例。如果isSingleton()返回true,则该实例会放到Spring容器的单实例缓存池中。
boolean isSingleton():确定由FactoryBean创建的Bean的作用域是singleton还是prototype。
Class<?> getObjectType() :返回FactoryBean创建的Bean的类型。
当配置文件中的bean的class属性配置的实现类是FactoryBean时,通过getBean()方法返回的不是FactoryBean本身,而是FactoryBean#getObject()方法所返回的对象,相当于FactoryBean#getObject()代理了getBean()方法。
下面是一个实现了FactoryBean接口的类的示例:
public class CarFactoryBean implements FactoryBean<Car>{
private String carInfo;
//接受逗号分隔的属性设置信息
public void setCarInfo(String carInfo) {
this.carInfo = carInfo;
}
public String getCarInfo(){
return carInfo;
}
//实例化car bean
@Override
public Car getObject() throws Exception {
Car car = new Car();
String[] infos = carInfo.split(",");
car.setBrand(infos[0]);
car.setMaxSpeed(Integer.parseInt(infos[1]));
car.setPrice(Double.parseDouble(infos[2]));
return car;
}
//返回Car的类型
@Override
public Class<Car> getObjectType() {
return null;
}
//标识通过该FactoryBean返回的Bean是singleton
@Override
public boolean isSingleton() {
return false;
}
}
那么在beans.xml中的配置为:
<bean id="car" class="com.smart.fb.CarFactoryBean"
p:carInfo="宝马,200,50000.00" />
当调用getBean(“car”)时,Spring通过反射机制发现CarFactoryBean实现了FactoryBean的接口,这是Spring容器就调用接口方法CarFactoryBean#getObject()返回该工厂类创建的对象。如果用户希望获取CarFactoryBean的实例,则需要在使用getBean(beanName)方法时显式的在beanName前加上“&”前缀,即getBean(“&car”)。
以上是FactoryBean的介绍。