跳至主要內容

12、Spring initializeBean源码分析

安图新大约 7 分钟

12、Spring initializeBean源码分析

一,initializeBean 方法概述

Spring 中的 initializeBean()方法是 doCreateBean 方法三部曲的最后一步,完成 initializeBean()则整个 bean 的创建过程才算完成,我们来看一下 bean 的创建过程 doCreateBean()方法中三部曲:实例化(createBeanInstance),填充属性(populateBean),初始化(initializeBean)。

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {


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



        // 省略部分代码....

		// 第一步:实例化bean
		instanceWrapper = createBeanInstance(beanName, mbd, args);

		// 为避免后期循环依赖,提前曝露ObjectFactory到第三级缓存中。
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

        // 第二步:填充属性
		populateBean(beanName, mbd, instanceWrapper);

		// 第三步:执行初始化逻辑
		exposedObject = initializeBean(beanName, exposedObject, mbd);

	}
}

本文主要分析是 initializeBean 初始化,关于前面两步 “实例化” 和 “填充属性” 两步,请参考:

Spring 实例化(createBeanInstance)源码解析open in new window

Spring 属性填充 populateBean 源码分析open in new window


initializeBean 初始化主要分为如下几个步骤:

1、 执行 aware 接口 invokeAwareMethods;
2、 执行 BeanPostProcessor 的 postProcessBeforeInitialization()方法;
3、 执行初始化方法 invokeInitMethods;
4、 执行 BeanPostProcessor 的 postProcessAfterInitialization()方法;

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {



		// Aware接口处理器,调用BeanNameAware、BeanClassLoaderAware、beanFactoryAware
		invokeAwareMethods(beanName, bean);

		// 调用BeanPostProcessor的postProcessBeforeInitialization方法。
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

		// 调用初始化方法,先调用bean的InitializingBean接口方法,后调用bean的自定义初始化方法
		invokeInitMethods(beanName, wrappedBean, mbd);

    	// 调用BeanPostProcessor的applyBeanPostProcessorsAfterInitialization方法。
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

		//返回包装后的Bean
		return wrappedBean;
	}

我们从上面可以看到,在 beanPostProcessor 接口的 postProcessBeforeInitialization()方法和 postProcessAfterInitialization()方法都可以对最终的 bean 做修改或替换。

如果我们配置的有 Aop 代理的话,会在执行 AbstractAutoProxyCreator 类的 postProcessAfterInitialization()方法时创建此 bean 代理对象,并且把此代理对象放入 bean 容器中。

二,执行 aware 接口 invokeAwareMethods

这个方法就是判断一下当前 bean 是否实现了 BeanNameAware,BeanClassLoaderAware,BeanFactoryAware 接口,如果实现了,就回调相应的方法。比较简单,没啥好说的,直接看源码就行了:

private void invokeAwareMethods(String beanName, Object bean) {


		//如果 bean 是 Aware 实例
		if (bean instanceof Aware) {


			//如果bean是BeanNameAware实例
			if (bean instanceof BeanNameAware) {


				//调用 bean 的setBeanName方法
				((BeanNameAware) bean).setBeanName(beanName);
			}
			//如果bean是 BeanClassLoaderAware 实例
			if (bean instanceof BeanClassLoaderAware) {


				//获取此工厂的类加载器以加载Bean类(即使无法使用系统ClassLoader,也只能为null)
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {


					//调用 bean 的 setBeanClassLoader 方法
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			//如果bean是 BeanFactoryAware 实例
			if (bean instanceof BeanFactoryAware) {


				// //调用 bean 的 setBeanFactory 方法
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

三,执行 BeanPostProcessor 的 postProcessBeforeInitialization()方法

postProcessBeforeInitialization()方法会在执行 init 方法之前调用,遍历 beanPostProcessors 集合调用 postProcessBeforeInitialization()方法。

	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {



		//初始化返回结果为existingBean
		Object result = existingBean;
		//遍历 该工厂创建的bean的BeanPostProcessors列表
		for (BeanPostProcessor processor : getBeanPostProcessors()) {


			// postProcessBeforeInitialization:在任何Bean初始化回调之前(如初始化Bean的afterPropertiesSet或自定义的init方法)
			// 将此BeanPostProcessor 应用到给定的新Bean实例。Bean已经填充了属性值。返回的Bean实例可能时原始Bean的包装器。
			// 默认实现按原样返回给定的 Bean
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			// 如果 current为null
			if (current == null) {


				//直接返回result,中断其后续的BeanPostProcessor处理
				return result;
			}
			//让result引用processor的返回结果,使其经过所有BeanPostProcess对象的后置处理的层层包装
			result = current;
		}
		//返回经过所有BeanPostProcess对象的后置处理的层层包装后的result
		return result;
	}

1,ApplicationContextAwareProcessor 调用 Aware 接口方法

主要完成,判断当前 bean 是否实现 EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware 接口,如果实现则对其方法进行调用。

class ApplicationContextAwareProcessor implements BeanPostProcessor {


     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {


		if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
				bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
				bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){


			return bean;
		}

		AccessControlContext acc = null;

		if (System.getSecurityManager() != null) {


			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {


			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {


				// 检测bean上是否实现了某个aware接口,有的话进行相关的调用
				invokeAwareInterfaces(bean);
				return null;
			}, acc);
		}
		else {


			invokeAwareInterfaces(bean);
		}

		return bean;
	}
}

2,ConfigurationClassPostProcessor 调用 ImportAware 接口方法

如果 bean 实现了 ImportAware 接口,就会设置 bean 的注解信息:

	public Object postProcessBeforeInitialization(Object bean, String beanName) {


			if (bean instanceof ImportAware) {


				ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
				AnnotationMetadata importingClass = ir.getImportingClassFor(ClassUtils.getUserClass(bean).getName());
				if (importingClass != null) {


					((ImportAware) bean).setImportMetadata(importingClass);
				}
			}
			return bean;
		}

3,InitDestroyAnnotationBeanPostProcessor 调用被注解修饰的生命周期方法

在 doCreateBean 中,createBeanInstance 实例化完成之后,populateBean 填充属性执行之前,会执行 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)方法:

	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {


		for (BeanPostProcessor bp : getBeanPostProcessors()) {


			if (bp instanceof MergedBeanDefinitionPostProcessor) {


				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
			}
		}
	}

目的是允许 beanPostProcessor 去修改合并的 beanDefinition,其中会执行 InitDestroyAnnotationBeanPostProcessor 类的 postProcessMergedBeanDefinition()方法:

	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {


		// 调用方法获取生命周期元数据并保存
		LifecycleMetadata metadata = findLifecycleMetadata(beanType);
		// 验证相关方法
		metadata.checkConfigMembers(beanDefinition);
	}

会获取当前 bean 中包含的被@PostContruct 和@PreDestroy 注解标注的方法存储在 lifecycleMetadataCache 的 map 中。


所以在 InitDestroyAnnotationBeanPostProcessor 类的 postProcessBeforeInitialization()方法中会通过反射去调用上面缓存在 lifecycleMetadataCache 中的被@PostContruct 注解修饰的方法:

	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {


		LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
		try {


			metadata.invokeInitMethods(bean, beanName);
		}
		catch (InvocationTargetException ex) {


			throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
		}
		catch (Throwable ex) {


			throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
		}
		return bean;
	}

四,执行初始化方法 invokeInitMethods

如果 bean 实现了 InitializingBean 接口,则先执行 InitializingBean 接口的 afterPropertiesSet 方法。

然后执行 xml 或注解设置的 init-method 方法。

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
			throws Throwable {



    // 省略部分代码...

	// 调用bean的afterPropertiesSet方法
	((InitializingBean) bean).afterPropertiesSet();

	// 在bean上调用指定的自定义init方法
	invokeCustomInitMethod(beanName, bean, mbd);

}

五,执行 BeanPostProcessor 的 postProcessAfterInitialization()方法

遍历 beanPostProcessors 集合,执行 BeanPostProcessor 的后置处理器:

	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {



		//初始化结果对象为result,默认引用existingBean
		Object result = existingBean;
		//遍历该工厂创建的bean的BeanPostProcessors列表
		for (BeanPostProcessor processor : getBeanPostProcessors()) {


			//回调BeanPostProcessor#postProcessAfterInitialization来对现有的bean实例进行包装
			Object current = processor.postProcessAfterInitialization(result, beanName);
			//一般processor对不感兴趣的bean会回调直接返回result,使其能继续回调后续的BeanPostProcessor;
			// 但有些processor会返回null来中断其后续的BeanPostProcessor
			// 如果current为null
			if (current == null) {


				//直接返回result,中断其后续的BeanPostProcessor处理
				return result;
			}
			//让result引用processor的返回结果,使其经过所有BeanPostProcess对象的后置处理的层层包装
			result = current;
		}
		//返回经过所有BeanPostProcess对象的后置处理的层层包装后的result
		return result;
	}

1,AbstractAutoProxyCreator 生成 aop 代理对象

如果使用了 aop 代理,那么此处会生成代理对象,替换原生 bean 对象。

	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {


		if (bean != null) {


			// 根据给定bean的name和class构建出一个key
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {


				// 如果它需要被代理,则需要封装指定的bean
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

首先查看是否在 earlyProxyReferences 缓存中存在,如果有就说明处理过了,不存在就考虑是否需要被代理,如需要则创建代理对象(对原生 bean 封装)。

2,ApplicationListenerDetector 检测 bean 是否实现了 ApplicationListener 接口

如果 bean 是单例的并且实现了 ApplicationListener 接口,则加入到多播器中 applicationEventMulticaster。

public Object postProcessAfterInitialization(Object bean, String beanName) {


		if (bean instanceof ApplicationListener) {


			// 判断当前bean是否是单例,如果是的话,直接添加到容器的监听器集合中
			Boolean flag = this.singletonNames.get(beanName);
			if (Boolean.TRUE.equals(flag)) {


				// 添加到容器的监听器集合中
				this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
			}
			// 如果不是单例的,并且又是一个嵌套的bean,那么打印日志,提示内嵌的bean只有在单例的情况下才能作为事件监听器

		}
		return bean;
	}

六,总结

生命周期执行顺序:

1、 @PostConstruct 注解修饰的方法;
2、 InitializingBean 接口的 afterPropertiesSet()方法;
3、 init-method 指定的方法;
4、 @PreDestroy 注解修饰的方法;
5、 DisposableBean 接口的 destroy()方法;
6、 destory-method 指定的方法;

上次编辑于:
贡献者: Andy