【spring】Bean的生命周期之生成非懒加载的单例Bean

生成非懒加载的单例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<String> 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<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) {
		// 找到当前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<Object>) () -> {
					smartSingleton.afterSingletonsInstantiated();
					return null;
				}, getAccessControlContext());
			}
			else {
				// 直接调用这个Bean重写的方法
				smartSingleton.afterSingletonsInstantiated();
			}
			// 一个计时器结束位置
			smartInitialize.end();
		}
	}
}

判断是否是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!
  • 这个公众号,无广告!!!每日更新!!!
    作者公众号.jpg
posted @ 2022-02-22 23:41  程序java圈  阅读(76)  评论(0编辑  收藏  举报