前言
让我们继续讲解Spring的Bean实例化过程。在上一节中,我们已经讲解了Spring是如何将Bean定义加入到IoC容器中,并使用合并的Bean定义来包装原始的Bean定义。接下来,我们将继续讲解Spring的 getBean()
方法,特别是针对 FactoryBean
的解析。
在 getBean()
方法中,Spring还支持对 FactoryBean
进行特殊处理。FactoryBean
是一个能够生成Bean实例的工厂Bean,其定义了 getObject()
方法,返回的是一个由工厂Bean管理的对象实例。在使用 getBean()
方法获取 FactoryBean
类型的Bean时,Spring会首先获取 FactoryBean
的实例,然后调用其 getObject()
方法来获取由工厂Bean创建的实际Bean实例。
因此,在使用 getBean()
方法获取Bean实例时,我们需要注意是否需要对 FactoryBean
进行特殊处理。如果需要获取 FactoryBean
的实例而不是它所管理的对象实例,可以在Bean名称前加上 &
符号来进行标识。例如:&myFactoryBean
表示获取 myFactoryBean
的实例。但是博主看到第一篇源码写的篇幅确实有些长,可能对于大家伙的碎片化时间掌握的不是很充分,所以以后我会尽力控制篇幅长度,既保证逻辑的连续性也保证尽快可以看完,那么接下来开始进入正题getbean方法之FactoryBean解析。
FactoryBean
所有符合过滤条件的Bean在Spring解析后都会被转化为合并后的Bean定义。尽管Spring提供了 getBean()
方法用于获取Bean实例,但实际上它底层仍然使用 createBean()
方法来创建Bean实例。在创建Bean实例之前,Spring先对当前Bean定义进行判断,以确定其是否为 FactoryBean
类型:
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine. List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
// 获取合并后的BeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// 获取FactoryBean对象
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
// 创建真正的Bean对象(getObject()返回的对象)
getBean(beanName);
}
}
}
else {
// 创建Bean对象
getBean(beanName);
}
}
}
// 所有的非懒加载单例Bean都创建完了后
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
}
他的源码逻辑大致如下:
- Spring会根据
beanName
去bean
定义Map
中获取当前合并的Bean
定义。 - Spring会对当前
Bean
定义进行判断,包括判断当前Bean
是否为抽象的、是否为单例、是否懒加载,以及是否为FactoryBean
。如果是FactoryBean
,则会走FactoryBean
的创建逻辑