生成非懒加载的单例Bean
- 本文源码基于spring-framework-5.3.10。
- FactoryBean会生成一个BeanDefinition俩个Bean对象。
源码关注重点
- FactoryBean的对象什么时候真正的创建
- 实现了SmartInitializingSingleton的Bean的方法是什么时候执行的
生成非懒加载的单例Bean的主要流程
- 得到所有bean的名字,遍历
- 合并BeanDefinition(父子BeanDefinition)
- Bean的创建:普通Bean直接创建,FactoryBean先创建类中的Bean,getObject的对象按照条件看是否直接创建
- 所有Bean创建完成后,找到实现了SmartInitializingSingleton的Bean,执行他的afterSingletonsInstantiated方法
本文源码入口
// 1、创建AnnotationConfigApplicationContext对象
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
// 2、他会调用refresh();刷新方法
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
.......
refresh();
}
// 3、调用初始化bean工厂方法
public void refresh() throws BeansException, IllegalStateException {
......
finishBeanFactoryInitialization(beanFactory);
......
}
// 4、调用实例化非懒加载的单例Bean方法
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
......
beanFactory.preInstantiateSingletons();
}
生成非懒加载的单例Bean源码分析
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.
// 得到所有的Bean名字
List beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
// 获取合并(xml方式配置parent=另一个BeanName)后的BeanDefinition,并放入mergedBeanDefinitions这个Map中
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 不是抽象的BeanDefinition(xml方式配置abstract=true),并且它是单例的,并且他不是懒加载的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// FactoryBean的逻辑
if (isFactoryBean(beanName)) {
// 获取FactoryBean对象(类对象)
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
// 他是FactoryBean
if (bean instanceof FactoryBean) {
// 强转为FactoryBean
FactoryBean<?> factory = (FactoryBean<?>) bean;
// 是否要初始化的判断标志
boolean isEagerInit;
// 当他实现了SmartFactoryBean的时候,并且重写的isEagerInit为true才会吧isEagerInit设置为true,进行getObject()的Bean的创建
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction) ((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) {
// 找到当前beanName对应的单例对象
Object singletonInstance = getSingleton(beanName);
// 所有的非懒加载单例Bean创建完成之后,调用当前Bean实现了SmartInitializingSingleton接口的方法。针对单个Bean
if (singletonInstance instanceof SmartInitializingSingleton) {
// 一个计时器开始位置
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
// 强转为我们的实现类
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
// 通过JDK的安全处理器方式调用这个Bean重写的方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
判断是否是FactoryBean源码分析
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
// 找到当前beanName对应的单例对象:
Object beanInstance = getSingleton(beanName, false);
// 不为空的时候,直接返回他是否属于FactoryBean
if (beanInstance != null) {
return (beanInstance instanceof FactoryBean);
}
// No singleton instance found -> check bean definition.
// 走到这里说明没有拿到,只能根据BeanDefinition进行判断。
// 当前容器beanDefinitionMap中没有当前Bean并且父BeanFactory是配置类
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
// 返回父BeanFactory的isFactoryBean。
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
// 当前容器中包含这个Bean,判断当前Bean是否是FactoryBean,走这个方法判断
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
/**
* 当前容器中包含这个Bean,判断当前Bean是否是FactoryBean
*/
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
// 看这个BeanDefinition的isFactoryBean属性,是否是值
Boolean result = mbd.isFactoryBean;
if (result == null) {
// 获取BeanDefinition的beanClass属性,没有就去加载这个具体的Bean(依赖注入的时候去深入分析这个方法)
Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
// 判断是不是实现了FactoryBean接口
result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
// 设置到当前BeanDefinition的isFactoryBean属性
mbd.isFactoryBean = result;
}
// 拿到返回值
return result;
}
结束语
- 获取更多本文的前置知识文章,以及新的有价值的文章,让我们一起成为架构师!
- 关注公众号,可以让你对MySQL、并发编程、spring源码有深入的了解!
- 关注公众号,后续持续高效的学习JVM!
- 这个公众号,无广告!!!每日更新!!!