说明:
??1. 本文基于Spring-Framework 5.1.x版本讲解
??2. 建议读者对Mybatis有基本的使用经验
概述
这一篇我们讲讲org.springframework.beans.factory.FactoryBean
接口,这个接口功能非常强大,可以集成不同的中间件或组件到Spring容器中来,可以说该接口是打通Spring与外界沟通的重要桥梁,是Spring非常重要的一个拓展点。 不少人会拿BeanFactory
与FactoryBean
做比较,其实这两个接口根本就没有可比性,完全不是一个’层次‘的产物。废话不多说,让我们开始吧。
FactoryBean
先看下FatoryBean
接口在源码中的定义
/**
* 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.
*
* <p><b>NB: A bean that implements this interface cannot be used as a normal bean.</b>
* A FactoryBean is defined in a bean style, but the object exposed for bean
* references ({@link #getObject()}) is always the object that it creates.
*
* <p>FactoryBeans can support singletons and prototypes, and can either create
* objects lazily on demand or eagerly on startup. The {@link SmartFactoryBean}
* interface allows for exposing more fine-grained behavioral metadata.
*
* <p>This interface is heavily used within the framework itself, for example for
* the AOP {@link org.springframework.aop.framework.ProxyFactoryBean} or the
* {@link org.springframework.jndi.JndiObjectFactoryBean}. It can be used for
* custom components as well; however, this is only common for infrastructure code.
*
* <p><b>{@code FactoryBean} is a programmatic contract. Implementations are not
* supposed to rely on annotation-driven injection or other reflective facilities.</b>
* {@link #getObjectType()} {@link #getObject()} invocations may arrive early in the
* bootstrap process, even ahead of any post-processor setup. If you need access to
* other beans, implement {@link BeanFactoryAware} and obtain them programmatically.
*
* <p><b>The container is only responsible for managing the lifecycle of the FactoryBean
* instance, not the lifecycle of the objects created by the FactoryBean.</b> Therefore,
* a destroy method on an exposed bean object (such as {@link java.io.Closeable#close()}
* will <i>not</i> be called automatically. Instead, a FactoryBean should implement
* {@link DisposableBean} and delegate any such close call to the underlying object.
*
* <p>Finally, FactoryBean objects participate in the containing BeanFactory's
* synchronization of bean creation. There is usually no need for internal
* synchronization other than for purposes of lazy initialization within the
* FactoryBean itself (or the like).
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 08.03.2003
* @param <T> the bean type
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.aop.framework.ProxyFactoryBean
* @see org.springframework.jndi.JndiObjectFactoryBean
*/
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
default boolean isSingleton() { return true; }
}
从接口描述信息中我们可以得到以下几点关键信息:
1. 实现了BeanFactory
接口的Bean,实际上对外暴露的是getObject
方法返回的对象;
2. FactoryBean
支持创建单例和原型Bean,可以通过懒加载或容器启动时加载的方式创建Bean,可以实现SmartFactoryBean
接口来控制更多的Bean创建方式;
3. Spring只会管理FactoryBean
对象本身,通过FactoryBean#getObject
创建出来的对象的生命周期则不会由Spring管理。 也就是说通过getObject
返回的对象本身即使实现了生命周期接口,也不会被调用;