FactoryBean是定义在Spring中的一个带泛型的接口,从字面意思我们可以理解为一个工厂Bean,工厂Bean的作用就是帮助我们生成我们所需要的定制化的Bean,我们在以往的项目中如果单纯的利用在 @Configuration
的配置类去实例化这种复杂的对象,势必会导致Configuration配置的越来越复杂,所以我们就可以借助FactoryBean把某些复杂的配置的封装起来。
FactoryBean还有一个作用就是用来提供给第三方插件用来整合Spring,例如Mybatis的org.mybatis.spring.SqlSessionFactoryBean
。
一起看下FactoryBean的定义:
根据官方文档介绍:
- FactoryBean,就是单个对象的工厂类,和普通的Bean不一样,该工厂类所持有的对象引用应该是
getObject()
方法实际创建并返回的Bean而不是它本身。尽管Spring容器在启动时会以普通Bean
创建的方式一样去创建FactoryBean。 - FactoryBean支持单例和多例,根据
isSingleton()
返回值来确定是否是单例,默认为true。 - FactoryBean生成的Bean,支持懒加载或者在容器启动阶段就同步创建Bean,如果需要同步创建Bean则可以选择实现
SmartFactoryBean
,该接口继承FactoryBean
并提供是否支持同步创建Bean的实例SmartFactoryBean#isEagerInit()
SmartFactoryBean定义:
- SmartFactoryBean 继承自
FactoryBean
,并提供了扩展方法,FactoryBean 创建的实例Bean默认是在第一次获取时创建,如果需要在容器启动时同步创建Bean实例可以重写isEagerInit()
,true表示容器创建阶段就会调用getObject()
去实例化对应的Bean实例。
源码分析如下(已删减部分源码):
- 容器启动:
AnnotationConfigApplicationContext(java.lang.Class<?>...)
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { this(); register(annotatedClasses); // 1. 容器启动 refresh(); }
AbstractApplicationContext#refresh
>finishBeanFactoryInitialization
@Override public void refresh() throws BeansException, IllegalStateException { ...... // 2. 开始实例化所有的单例Bean // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); ...... } /** * Finish the initialization of this context's bean factory, * initializing all remaining singleton beans. */ protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); }
- BeanFactory准备创建Bean:
DefaultListableBeanFactory#preInstantiateSingletons
@Override public void preInstantiateSingletons() throws BeansException { ...... // Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { // 判断是否时FactoryBean if (isFactoryBean(beanName)) { // 第一次是创建FactoryBean本身,FactoryBean本身需要用 & + beanName 去获取 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { final FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { // 是否实现的FactoryBean为SmartFactoryBean 且 isEagerInit()是否为true isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } // 第二次调用 getBean // isEagerInit为true则需要同步创建FactoryBean产生的Bean实例 // 即 FactoryBean#getObject() if (isEagerInit) { // 3. 创建FactoryBean生产出来的Bean getBean(beanName); } } } else { // 其他的单例类在这里实例化 getBean(beanName); } } } ...... }
AbstractBeanFactory#doGetBean
从上面我们可以看出,getBean() 方法在遇到FactoryBean一共会调用两次,第一次是实例化 FactoryBean本身,而第二次调用才是真正去实例化FactoryBean产生的Bean实例,前提是实现了SmartFactoryBean
且isEagerInit
为true。protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { // 解析beanName final String beanName = transformedBeanName(name); Object bean; // 第一次创建FactoryBean本身之后 // 根据上面的isEagerInit第二次到这里 sharedInstance 就不为空了 // Eagerly check singleton cache for manually registered singletons. Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { ...... // 4. FactoryBean产生的Bean实例在这里去实例化 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // 正常的单例Bean会在这里创建并返回 // Create bean instance. if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } } ...... return (T) bean; }
AbstractBeanFactory#getObjectForBeanInstance
protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory. if (BeanFactoryUtils.isFactoryDereference(name)) { if (beanInstance instanceof NullBean) { return beanInstance; } if (!(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass()); } } // 正常的Bean在这里就直接返回 // Now we have the bean instance, which may be a normal bean or a FactoryBean. // If it's a FactoryBean, we use it to create a bean instance, unless the // caller actually wants a reference to the factory. if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } Object object = null; if (mbd == null) { object = getCachedObjectForFactoryBean(beanName); } if (object == null) { // Return bean instance from factory. FactoryBean<?> factory = (FactoryBean<?>) beanInstance; // Caches object obtained from FactoryBean if it is a singleton. if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); // 5. 从FactoryBean中获取对应的Bean实例 object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
FactoryBeanRegistrySupport#getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { // 单例的工厂Bean if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { // 6. 创建FactoryBean产生的实例 object = doGetObjectFromFactoryBean(factory, beanName); ...... } } return object; } } // 非单例的工厂Bean else { Object object = doGetObjectFromFactoryBean(factory, beanName); if (shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex); } } return object; } }
FactoryBeanRegistrySupport#doGetObjectFromFactoryBean
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) throws BeanCreationException { Object object; try { if (System.getSecurityManager() != null) { AccessControlContext acc = getAccessControlContext(); try { object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { // 7. 调用FactoryBean#getObject() // 至此 FactoryBean产生的实例就创建好了 object = factory.getObject(); } } ...... return object; }