Spring
源码 - 核心接口FactoryBean
Spring
版本:Spring 5.3.13-release
一般情况下,Spring
是通过反射机制,利用在Bean
进行声明时的class
属性指定的实现类来进行Bean
的实例化操作。但是在某些场景下,Bean
的实例化操作时非常复杂繁琐的,如果按照传统的方式,则需要在<bean></bean>
中进行大量配置信息的声明,这种配置方式的灵活性会受到非常大的局限性的。而如果采用编码的方式进行声明可能会变得非常简单。org.springframework.beans.factory.FactoryBean<T>
接口应运而生,用户可以实现该接口来定制实例化Bean
的逻辑。
# 1、核心接口FactoryBean
FactoryBean<T>
在Spring
占据非常重要的地位。很多第三方中间件都是通过实现FactoryBean<T>
接口进行实例化。如open-feign
。
FactoryBean<T>
接口中一共定义了三个方法:
public interface FactoryBean<T> {
/**
* The name of an attribute that can be
* {@link org.springframework.core.AttributeAccessor#setAttribute set} on a
* {@link org.springframework.beans.factory.config.BeanDefinition} so that
* factory beans can signal their object type when it can't be deduced from
* the factory bean class.
* @since 5.2
*/
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
/**
* Return an instance (possibly shared or independent) of the object
* managed by this factory.
* <p>As with a {@link BeanFactory}, this allows support for both the
* Singleton and Prototype design pattern.
* <p>If this FactoryBean is not fully initialized yet at the time of
* the call (for example because it is involved in a circular reference),
* throw a corresponding {@link FactoryBeanNotInitializedException}.
* <p>As of Spring 2.0, FactoryBeans are allowed to return {@code null}
* objects. The factory will consider this as normal value to be used; it
* will not throw a FactoryBeanNotInitializedException in this case anymore.
* FactoryBean implementations are encouraged to throw
* FactoryBeanNotInitializedException themselves now, as appropriate.
* @return an instance of the bean (can be {@code null})
* @throws Exception in case of creation errors
* @see FactoryBeanNotInitializedException
* @see FactoryBean#isSingleton()
* @see org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#singletonObjects
*/
@Nullable
T getObject() throws Exception;
/**
* Return the type of object that this FactoryBean creates,
* or {@code null} if not known in advance.
* <p>This allows one to check for specific types of beans without
* instantiating objects, for example on autowiring.
* <p>In the case of implementations that are creating a singleton object,
* this method should try to avoid singleton creation as far as possible;
* it should rather estimate the type in advance.
* For prototypes, returning a meaningful type here is advisable too.
* <p>This method can be called <i>before</i> this FactoryBean has
* been fully initialized. It must not rely on state created during
* initialization; of course, it can still use such state if available.
* <p><b>NOTE:</b> Autowiring will simply ignore FactoryBeans that return
* {@code null} here. Therefore it is highly recommended to implement
* this method properly, using the current state of the FactoryBean.
* @return the type of object that this FactoryBean creates,
* or {@code null} if not known at the time of the call
* @see ListableBeanFactory#getBeansOfType
*/
@Nullable
Class<?> getObjectType();
/**
* Is the object managed by this factory a singleton? That is,
* will {@link #getObject()} always return the same object
* (a reference that can be cached)?
* <p><b>NOTE:</b> If a FactoryBean indicates to hold a singleton object,
* the object returned from {@code getObject()} might get cached
* by the owning BeanFactory. Hence, do not return {@code true}
* unless the FactoryBean always exposes the same reference.
* <p>The singleton status of the FactoryBean itself will generally
* be provided by the owning BeanFactory; usually, it has to be
* defined as singleton there.
* <p><b>NOTE:</b> This method returning {@code false} does not
* necessarily indicate that returned objects are independent instances.
* An implementation of the extended {@link SmartFactoryBean} interface
* may explicitly indicate independent instances through its
* {@link SmartFactoryBean#isPrototype()} method. Plain {@link FactoryBean}
* implementations which do not implement this extended interface are
* simply assumed to always return independent instances if the
* {@code isSingleton()} implementation returns {@code false}.
* <p>The default implementation returns {@code true}, since a
* {@code FactoryBean} typically manages a singleton instance.
* @return whether the exposed object is a singleton
* @see #getObject()
* @see SmartFactoryBean#isPrototype()
*
* 返回由 FactoryBean 创建的 Bean 实例的作用域是单例还是原型
* true -> singleton / false -> prototype
*/
default boolean isSingleton() {
return true;
}
}
getObject()
:返回由FactoryBean
创建的Bean
实例,如果isSingleton()
返回true
,则该Bean
实例会放入Spring
的一级缓存中。getObjectType()
:返回FactoryBean
创建的Bean
类型。isSingleton()
:返回由FactoryBean
创建的Bean
实例的作用域是单例还是原型。
当声明Bean
时指定的class
属性为FactoryBean<T>
接口的实现类时,Spring
容器通过getBean()
方法获取的Bean
实例为T
,即为getObject()
方法返回的实例对象。也就是说此时FactoryBean<T>#getObject()
方法代理了getBean()
方法。如果需要获取此FactoryBean<T>
实例,则需要通过&
+BeanName
进行获取。
# 2、BeanFactory
与FactoryBean<T>
需要注意的是,BeanFactory
与FactoryBean<T>
是两个完全不同概念的接口。BeanFactory
根据命名可以看出,它是一个工厂。而FactoryBean<T>
根据命名也可以很清晰的看出,它是一个Bean
。BeanFactory
是Spring
对于IOC
思想实现的最基本方式,它提供了对Bean
的管理。而FactoryBean<T>
是Spring
针对复杂类型Bean
的实例化,允许开发者对此类型的Bean
进行的高级定制处理。
GitHub源码地址:https://github.com/kapbc/kapcb-spring-source/tree/master/Spring-Framework-v5.3.13
备注:此文为笔者学习
Spring
源码的笔记,鉴于本人技术有限,文中难免出现一些错误,感谢大家批评指正。