简介
创建对象最简单的方式是直接使用new操作符,如果创建对象比较繁杂,可以采用工厂模式。同样Spring中提供了FactoryBean接口来帮助创建对象。
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
- T getObject():返回由FactoryBean创建的bean实例。bean示例可能是singleton还是prototype取决于isSingleton方法的返回。
- boolean isSingleton():返回由FactoryBean创建的bean实例的作用域是singleton还是prototype。
- Class<T> getObjectType():返回FactoryBean创建的bean类型。
在Spring中,创建bean时,如果该bean实现了FactoryBean接口,那么就会调用getObject方法获取真正的bean, 通过 getBean()方法返回的不是FactoryBean本身,而是FactoryBean#getObject()方法所返回的bean。如果想要获取FactoryBean本身,在beanName前显示的加上 "&" 前缀, 例如getBean("&myBean")。
用途:
Spring代理
Spring代理的实现类ProxyFactoryBean,当实例化ProxyFactoryBean时,对原有的singletonInstance对象进行封装,返回的是一个代理对象。Spring常用的AOP,以及事务注解都是基于Spring代理实现。
public class ProxyFactoryBean extends ProxyCreatorSupport implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware {
@Nullable
private Object singletonInstance; //原有对象
@Nullable
public Object getObject() throws BeansException {
this.initializeAdvisorChain();
if (this.isSingleton()) {
return this.getSingletonInstance();
} else {
if (this.targetName == null) {
this.logger.info("Using non-singleton proxies with singleton targets is often undesirable. Enable prototype proxies by setting the 'targetName' property.");
}
return this.newPrototypeInstance(); //返回代理后的对象
}
}
public Class<?> getObjectType() {
synchronized(this) {
if (this.singletonInstance != null) {
return this.singletonInstance.getClass();
}
}
Class<?>[] ifcs = this.getProxiedInterfaces();
if (ifcs.length == 1) {
return ifcs[0];
} else if (ifcs.length > 1) {
return this.createCompositeInterface(ifcs);
} else {
return this.targetName != null && this.beanFactory != null ? this.beanFactory.getType(this.targetName) : this.getTargetClass();
}
}
public boolean isSingleton() {
return this.singleton;
}
}
2.自定义bean工厂创建方法
public class CarFactoryBean implements FactoryBean<Car> {
private String carInfo;
public Car getObject() throws Exception {
Car car = new Car();
String[] infos = carInfo.split(",");
car.setBrand(infos[0]);
car.setMaxSpeed(Integer.valueOf(infos[1]));
car.setPrice(Double.valueOf(infos[2]));
return car;
}
public Class<Car> getObjectType() {
return Car.class;
}
public boolean isSingleton() {
return false;
}
}
配置文件添加
<bean id="car" class="com.test.factorybean.CarFactoryBean" carInfo="大众SUV,180,180000"/>
当调用getBean("car") 时,Spring会去调用getObject方法,获取的是Car对象,调用getBean("&car") 时,获取的是该CarFactoryBean示例。
参考:
[1].https://docs.spring.io/spring-framework/docs/4.3.15.RELEASE/spring-framework-reference/htmlsingle/#beans-factory-extension-factorybean
[2].FactoryBean的使用