Spring FactoryBean最佳实践

  • 扩展点简述

官方描述: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接口。

比如,你有这样的设计点:

  1. 你想让spring从工厂方法中获取具体对象,而不是直接用对象自身实例化;
  2. 对你的bean再做一层工厂封装,屏蔽具体实现类细节;
  3. 你想屏蔽具体对象的创建细节,又想让spring管理Bean。
  4. 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, 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开发笔记。

你可能感兴趣的:(Spring FactoryBean最佳实践)