简介
在Spring框架中,SmartFactoryBean是一个扩展了FactoryBean接口的类,提供了额外的功能。FactoryBean是Spring中一个强大的接口,允许你定义如何创建对象实例,而不仅仅是直接通过反射来实例化bean。通过FactoryBean,你可以返回任意类型的对象,这给予了更大的灵活性。
新增的两个方法
- isPrototype(): 这个方法用于指示由FactoryBean创建的bean是否是原型(prototype)的。如果返回true,则每次从容器中请求该bean时,都会通过FactoryBean创建一个新的实例。这与isSingleton()方法相对,后者用于指示bean是否是单例的。在Spring 5.3之前,通常通过返回false的isSingleton()方法来表示原型bean,但新增的isPrototype()方法提供了更明确的方式来表达这一意图。
- isEagerInit(): 这个方法用于指示是否应该立即初始化由FactoryBean创建的bean。如果返回true,则Spring容器在应用上下文启动时就会创建并初始化该bean,而不仅仅是在第一次请求时。这允许你在应用启动时执行一些必要的初始化逻辑,而不是等到第一次使用时才进行。
源码
public interface SmartFactoryBean<T> extends FactoryBean<T> {
default boolean isPrototype() {
return false;
}
default boolean isEagerInit() {
return false;
}
}
public void preInstantiateSingletons() throws BeansException {
...省略...
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 创建所有非延迟加载的单例bean
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 判断是否是FactoryBean
if (isFactoryBean(beanName)) {
// getBean(beanName)获取的是FactoryBean创建的bean实例
// getBean("&"+beanName)获取FactoryBean本身
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
// 判断是否有代码运行权限,这里不做展开
// 感兴趣的可以看博客https://www.jianshu.com/p/dcebd60b4c25
if (System.getSecurityManager() != null
&& factory instanceof SmartFactoryBean) {
...省略...
}
else {
// 默认情况 FactoryBean 延迟创建bean
// 但如果是 SmartFactoryBean,而且设置其 eagerInit 值为 true
// 那么就进行提前创建
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
// 进行提前创建
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
...省略...
}