Spring源码学习(五) | Bean的实例化过程

前言

       上文分析学习了@Configuration配置类的相关知识点,本文则着重通过源码来分析学习Bean的实例化过程。我们在平常的开发当中,无时无刻都会涉及到bean,那么bean在spring容器中是如何被实例化出来的呢??创建bean的时候,bean里面的bean又是如何依赖进去的呢??熟悉了整个bean的实例化过程,在开发过程中对于Spring的一些拓展知识点的运用才能融会贯通。

Spring容器的启动

		// 实例化工厂,准备reader和scanner
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

		// 把AppConfig类注册为一个BeanDefinition,然后放到DefaultListableBeanFactory的beanDefinitionMap里面
		context.register(AppConfig.class);

		// 准备好bean工厂,实例化对象
		context.refresh();

context.refresh();
之前的学习分析中,Spring的启动流程核心代码主要如下,而Spring的实例化过程则是在context.refresh()中的finishBeanFactoryInitialization方法中完成的。

			try {
				postProcessBeanFactory(beanFactory);

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				// 执行一些已经注册过的BeanFactoryPostProcessor方法
				// 设置执行自定义的BeanFactoryPostProcessor
				invokeBeanFactoryPostProcessors(beanFactory);

				// 注册bean的BeanPostProcessor
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();
				initMessageSource();
				initApplicationEventMulticaster();
				onRefresh();
				
				registerListeners();

				// 实例化所有单例对象
				finishBeanFactoryInitialization(beanFactory);

				finishRefresh();
			}

Bean实例化前夕

首先看一看子路大神整理的流程图,参照这个流程图我们一步一步先学习下Spring bean的实例化前夕的流程逻辑
在这里插入图片描述

preInstantiateSingletons

从refresh()中的finishBeanFactoryInitialization跟进去,会进入preInstantiateSingletons方法,逻辑如下:

  • 从容器的beanDefinitionNames取出所有bean的名字
  • 遍历所有beanname进行bean的实例化(FactoryBean和普通bean分开处理)
	@Override
	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...
		// 触发所有非延迟加载单例bean的初始化,主要步骤为getbean
		for (String beanName : beanNames) {
			// 合并父BeanDefinition,xml文件里面配置父子类的时候用到
			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) {
							getBean(beanName);
						}
					}
				}
				else {
					// 普通bean
					getBean(beanName);
				}
			}
		}
 		.....
 }

getBean( ) —> doGetBean( )

从上面的流程跟进普通bean的创建方法getBean,里面逻辑如下(代码过长,省略部分代码):

  1. 处理beanDefinitionNames的name获得实际的beanname(这里处理时因为有可能是factorybean类型的bean,名字是以&开头需要特殊处理)
  2. 调用第一个getSingleton方法,从容器中获取 bean(疑问点:这里明明是创建bean为啥还要从容器获取bean??后续分析)
  3. 第一个getSingleton为true,则通过getObjectForBeanInstance,返回bean实例
  4. 第一个getSingleton为false,则开始创建
    4.1. 做一些检查,检查是否原型bean创建,检查beanfactory,处理一些依赖。这些不重要,简略说明跳过
    4.2. 调用第二个getSingleton创建bean,注意这个getSingleton和之前的getSingleton不是 同一个。
	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		// 通过name获取beanname,这里不直接使用name作为beanname原因是
		// 1.beanname有形如 &xxx的格式,
		// 2.别名
		String beanName = transformedBeanName(name);
		Object bean;

		// 这里正在初始化调用getSingleton(beanName)获取单例bean,为什么??创建实例和获取实例都会走这里逻辑
		// 普通类来说这里100%取出来为null
		// 还有一种情况不为null,lazy=true 懒加载时候通过getbean真正获取的时候也会初始化bean
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			// 如果是原型,则报错不应该在初始化的时候创建
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			// 检查是否存在bean工厂
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}

			//
			if (!typeCheckOnly) {
				// 添加到alreadyCreated set集合,表示已经创建过
				markBeanAsCreated(beanName);
			}

			StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
					.tag("beanName", name);
			try {
				if (requiredType != null) {
					beanCreation.tag("beanType", requiredType::toString);
				}
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
					// 处理一些依赖相关
					.....
				}

				// Create bean instance.
				// 如果是单例,则创建  核心
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				else if (mbd.isPrototype()) {
					//	创建原型bean
					.....
				}

				else {
					//创建其他bean
					.....
				}
		}

getSingleton —> singletonFactory.getObject() —>doCreateBean()

从第二个getSingleton 方法跟进去,一直到doCreateBean()方法就会来到真正的bean实例化开始的地方,逻辑如下:

  • 创建bean实例
  • 填充bean的属性
  • 初始化bean
  • 处理DisposableBean相关

提醒:这里注意一下addSingletonFactory这个方法,主要用于解决循环依赖。

	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			// 创建bean实例
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.
		// 处理后置处理器MergedBeanDefinitionPostProcessor,本文不关注这里跳过
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		Object exposedObject = bean;
		try {
			// 填充bean属性
			populateBean(beanName, mbd, instanceWrapper);
			// 初始化bean
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			....
		}

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			.....
		}

		// 是否实现了DisposableBean接口
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}
		return exposedObject;
	}

Bean的实例化

创建bean实例 createBeanInstance

创建bean实例实际上就是我们经常写的new XXX,只是spring源码这里核心逻辑在于判断使用那个构造器进行创建bean实例,之后通过反射创建对象。这里也是省略部分代码,只留下核心逻辑

  • 通过后置处理器SmartInstantiationAwareBeanPostProcessor决定返回哪些构造方法
  • 如果有返回则根据返回的方法数组中,再通过一系列复杂的计算算出最合适的构造方法创建bean实例(计算逻辑比较复杂这里不作阐述,有兴趣可拉下笔者github源码参照写的注释阅读)
  • 如果没返回则使用默认无参数的构造方法创建bean实例
  • 创建factorybean的bean实例
    在这里插入图片描述
	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		Class<?> beanClass = resolveBeanClass(mbd, beanName);
       
        ......
       
		//由后置处理器决定返回哪些构造方法
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// Preferred constructors for default construction?
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		// No special handling: simply use no-arg constructor.
		//使用默认的无参构造方法进行初始化
		return instantiateBean(beanName, mbd);
	}

这里作一点补充:
如何让一个类通过特殊构造方法创建bean实例呢??可以参照下面例子

@Component
public class BeanInitPostProcesser implements BeanFactoryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		GenericBeanDefinition index = (GenericBeanDefinition) beanFactory.getBeanDefinition("index");
		index.getConstructorArgumentValues().addGenericArgumentValue("com.demo.UserDao");
	}
}
@Component("index")
public class UserDaoImpl4 implements UserDao {

	@SuppressWarnings("rawtypes")
	Class clazz;

	@SuppressWarnings("rawtypes")
	public UserDaoImpl4(Class clazz){
		this.clazz = clazz;
	}

	@Override
	public void test() {
		System.out.println(this.clazz);

	}
}

填充bean的属性 populateBean

这个阶段主要是对bean的一些依赖进行注入。起到核心作用的是AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor俩个处理器。分别的作用是处理@Autowired注解和 @PostConstruct,@Resource、@WebServiceRef、@EJB等等注解

在这里插入图片描述

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		.........
		
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}
	
		.........

}

在这里插入图片描述

初始化bean initializeBean

初始化bean一共走了3个逻辑:

  • 检查Aware接口,设置bean名字,类加载器,beanfactory
  • 执行BeanPostProcessor的前置处理方法
  • 执行InitializingBean接口的afterPropertiesSet方法与initmethod
  • 执行BeanPostProcessor后置处理方法
	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			// 检查Aware接口,设置bean名字,类加载器,beanfactory
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			// 执行BeanPostProcessor的前置处理方法
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// afterPropertiesSet方法与initmethod
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			// 执行BeanPostProcessor后置处理方法
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

检查Aware接口,设置bean名字,类加载器,beanfactory

	private void invokeAwareMethods(String beanName, Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

处理DisposableBean相关 registerDisposableBeanIfNecessary

这个阶段主要处理实现了DisposableBean接口的类以及实现destroyMethod方法,主要用于bean销毁的时候调用处理相关逻辑。
在这里插入图片描述
在这里插入图片描述

总结

Bean的实例化过程:

  • 1.创建bean实例和BeanWrapper
  • 2.填充属性(依赖的bean或属性)
  • 3.检查是否实现相关Aware接口,决定是否填充bean名字,类加载器,beanfactory到bean的属性里面
  • 4.检查是否实现BeanPostProcessor接口,执行BeanPostProcessor的前置处理方法
  • 5.检查是否实现InitializingBean接口,执行InitializingBean的afterPropertiesSet方法
  • 6.检查是否自定义init-method方法,执行init-method方法
  • 7.检查是否实现BeanPostProcessor接口,执行BeanPostProcessor后置处理方法
  • 8.检查是否实现DisposableBean接口,执行实现了DisposableBean接口的destroy方法
  • 9.检查是否自定义destroy-method方法,执行destroy-method方法
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值