-
扩展点简述
官方描述:Interface to be implemented by objects used within a {@link BeanFactory} which are themselves factories for individual objects. If a bean implements this interface, it is used as a factory for an object to expose, not directly as a bean instance that will be exposed itself.
NB: A bean that implements this interface cannot be used as a normal bean. A FactoryBean is defined in a bean style, but the object exposed for bean references ({@link #getObject()}) is always the object that it creates.
The container is only responsible for managing the lifecycle of the FactoryBean instance, not the lifecycle of the objects created by the FactoryBean. Therefore, a destroy method on an exposed bean object (such as {@link java.io.Closeable#close()} will not be called automatically. Instead, a FactoryBean should implement {@link DisposableBean} and delegate any such close call to the underlying object.
由BeanFactory中使用的对象实现的接口,这些对象本身就是单个对象的工厂。
如果Bean实现此接口,则它将用作对象公开的工厂,而不是直接用作对象自身的Bean实例。
FactoryBean是用bean样式定义的,但是为bean引用公开的对象( getObject() )始终是它创建的对象。注意:实现此接口的bean不能用作普通bean,因为他是一个工厂类,所以依赖注入时请使用FactoryBean的泛型类型)。
推荐实现DisposableBean接口,因为容器只负责FactoryBean的生命周期,但不负责通过FactoryBean创建的对象的生命周期,所以需要你进行管理。
-
扩展点的生命周期及扩展点的执行时机
属于Spring容器的扩展,容器注册DefaultListableBeanFactory的时候,处于加载bean定义之前,容器把Bean载入List之后的时机,这个时机可以自定义Bean对象的创建方式。
-
扩展点的作用
定义一个FactoryBean来获取具体实例化对象,需要实现FactoryBean接口。
比如,你有这样的设计点:
- 你想让spring从工厂方法中获取具体对象,而不是直接用对象自身实例化;
- 对你的bean再做一层工厂封装,屏蔽具体实现类细节;
- 你想屏蔽具体对象的创建细节,又想让spring管理Bean。
- AOP的实现 ProxyFactoryBean类,请参照 org.springframework.aop.framework.ProxyFactoryBean
-
扩展点实战
/**
* 定义一个FactoryBean来获取具体实例化对象,需要实现FactoryBean接口。
*
* 同时实现DisposableBean接口是因为容器只负责FactoryBean的生命周期,
* 但不负责通过FactoryBean创建的对象的生命周期,所以需要你进行管理。
*
* 比如:
* 1. 你想让spring从工厂方法中获取具体对象
* 2. 对bean再做一层工厂封装,屏蔽具体实现类细节
* 3. 你想屏蔽具体对象的创建细节,又想让spring管理Bean
*/
@Component
public class TestFactoryBean implements FactoryBean<TestFactoryBean.TBn>, DisposableBean {
private static TBn tBn = new TBnImpl();
// Bean初始化时,会调用这个方法获取将要实例化对象
@Override
public TBn getObject() throws Exception {
System.out.println("Bean 实例化了 TBn");
return tBn;
}
@Override
public Class<?> getObjectType() {
return TBn.class;
}
@Override
public void destroy() throws Exception {
System.out.println("销毁TBn");
tBn = null;
}
// @Autowried注入时要注入TBn这个接口,而不是TestFactoryBean
static class TBnImpl implements TBn {
public String d;
public String f;
}
public interface TBn {
}
}
更多Spring扩展请查看专题Spring开发笔记。
网友评论