Spring框架FactoryBean接口的作用和应用
1.
https://blog.csdn.net/weixin_53391173/article/details/139922339
FactoryBean源码解读
FactoryBean 是 Spring 框架 beans.factory包中的一个接口,从字面意思可以理解为工厂bean,它是干什么的,类名上的泛型又是指什么,有什么作用?
注释看不懂没关系,先看一下它有哪些方法。
public interface FactoryBean<T> {
// 获取实例
@Nullable
T getObject() throws Exception;
// 获取实例的class类型
@Nullable
Class<?> getObjectType();
// 实例默认为单例
default boolean isSingleton() {
return true;
}
}
方法看完了,还是不知道它能干嘛,继续看它的子类。
子类真多,一个屏幕放不下,找几个看看。
FactoryBean的子类
先看两个简单的实现类:
1. AuthenticationManagerFactoryBean类
AuthenticationManagerFactoryBean是spring-boot-starter-security 框架中的一个类,这个类实现了FactoryBean, BeanFactoryAware 两个接口的功能。
BeanFactoryAware 接口在《Spring框架Aware接口的作用和应用》一文中已经介绍过,它是用于在当前类初始化时获取 BeanFactory 接口以供当前类使用的。
FactoryBean的泛型位置放置了一个类AuthenticationManager。
AuthenticationManagerFactoryBean实现了FactoryBean接口中3个方法
在getObject() 方法中创建了AuthenticationManager实例并返回。
在该方法的最后一行代码可以看出,AuthenticationManager的实例是交给ProviderManager 对象管理的。
因此,在getObjectType()方法中返回的是ProviderManager对象的class。
在 isSingleton()方法中返回的依旧是单例模式。
从以上代码的分析,我们可以得出一个结论,AuthenticationManagerFactoryBean类是用来创建AuthenticationManager对象实例的工厂bean类。
2. CronTriggerFactoryBean类
CronTriggerFactoryBean是Spring框架定时任务 org.springframework.scheduling.quartz 包中的一个类,这个类实现了FactoryBean, BeanNameAware, InitializingBean 3个接口的功能。
BeanNameAware 是用于在当前类初始化时获取当前类的bean名称的。
InitializingBean 接口是用于重写初始化方法的。
FactoryBean的泛型位置放置了一个类CronTrigger。
CronTrigger是定时任务的表达式对象。

在重写的 afterPropertiesSet() 初始化方法中,new 了一个 CronTriggerImpl对象并返回。
CronTriggerImpl位于定时任务框架 org.quartz中,它是CronTrigger的实现类。
接下来就是FactoryBean三个方法的实现:
getObject() 方法中直接初始化方法中创建的cronTrigger变量。
getObjectType()方法返回的是CronTrigger的class,它是CronTriggerImpl的超类。
isSingleton()方法中返回的是单例模式。
从以上代码的分析,我们也可以得出一个结论,CronTriggerFactoryBean类是用来创建CronTriggerFactory对象实例的工厂bean类。
再来看两个复杂一些的抽象类。
3. AbstractFactoryBean抽象类
AbstractFactoryBean实现了FactoryBean, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean 5个接口。
FactoryBean泛型位置的参数还是泛型。
BeanClassLoaderAware接口是用于在当前类初始化时获取类加载对象ClassLoader的。
BeanFactoryAware接口是用于在当前类初始化时获取BeanFactory的。
InitializingBean 接口是用于重写初始化方法的。
DisposableBean 接口是用于重写销毁方法的。
在初始化方法中,如果是单例则进行实例化:
protected abstract T createInstance() throws Exception;
@Override
@Nullable
public abstract Class<?> getObjectType();
@Override
public final T getObject() throws Exception {
if (isSingleton()) {
return (this.initialized ? this.singletonInstance : getEarlySingletonInstance());
}
else {
return createInstance();
}
}
实例化是个抽象方法,由其子类实现具体实例化逻辑。
getObjectType()也是抽象方法,由其子类实现。
getObject()是个final方法,子类不能更改,如果是单例则返回单例实例,否则每次调用返回一个新的实例。
在AbstractFactoryBean抽象类中,我们最关心的FactoryBean中的2个方法,一个由其子类实现,一个由抽象类实现。不管是子类还是抽象类,目的都是一样的。
4. ListFactoryBean类
ListFactoryBean是AbstractFactoryBean<List