Spring源码 - 核心接口FactoryBean

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、BeanFactoryFactoryBean<T>

需要注意的是,BeanFactoryFactoryBean<T>是两个完全不同概念的接口。BeanFactory根据命名可以看出,它是一个工厂。而FactoryBean<T>根据命名也可以很清晰的看出,它是一个BeanBeanFactorySpring对于IOC思想实现的最基本方式,它提供了对Bean的管理。而FactoryBean<T>Spring针对复杂类型Bean的实例化,允许开发者对此类型的Bean进行的高级定制处理。

GitHub源码地址https://github.com/kapbc/kapcb-spring-source/tree/master/Spring-Framework-v5.3.13

备注:此文为笔者学习Spring源码的笔记,鉴于本人技术有限,文中难免出现一些错误,感谢大家批评指正。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值