Spring-bean的生命周期总结

x33g5p2x  于2022-03-05 转载在 Spring  
字(3.8k)|赞(0)|评价(0)|浏览(255)

标准bean生命周期

Bean工厂实现应该尽可能支持标准Bean生命周期接口。整套初始化方法及其标准顺序如下:

BeanNameAware.setBeanName,
BeanClassLoaderAware.setBeanClassLoader,
BeanFactoryAware.setBeanFactory,
org.springframework.context.EnvironmentAware.setEnvironment,
org.springframework.context.EmbeddedValueResolverAware.setEmbeddedValueResolver,
org.springframework.context.ResourceLoaderAware.setResourceLoader,
org.springframework.context.ApplicationEventPublisherAware.setApplicationEventPublisher,org.springframework.context.MessageSourceAware.setMessageSource,
org.springframework.context.ApplicationContextAware.setApplicationContext,
org.springframework.web.context.ServletContextAware.setServletContext,
org.springframework.beans.factory.config.BeanPostProcessor.postProcessBeforeInitialization, // 实例化之前
InitializingBean.afterPropertiesSet, //实例化之后
org.springframework.beans.factory.support.RootBeanDefinition.getInitMethodName, // 初始化方法
org.springframework.beans.factory.config.BeanPostProcessor.postProcessAfterInitialization, // 初始化之后
org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor.postProcessBeforDestruction, // 关闭容器,销毁bean之前
DisposableBean.destroy,
org.springframework.beans.factory.support.RootBeanDefinition.getDestroyMethodName

bean生命周期分析

ClassPathXmlApplicationContext的构造函数开始作为入口分析:

整个生命周期大致如图所示:

bean初始化准备工作:

obtainFreshBeanFactory方法中先loadBeanDefinitions加载bean定义,然后创建beanFactory实例,以及其他一些系统必要组件的加载

开始生命周期

  1. 如果有则调用BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry
  2. 如果有则调用BeanFactoryPostProcessorpostProcessBeanFactory方法
  3. 如果有则调用InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation前置方法
    一个使用代理创建bean的机会,如果返回null,则开始正式创建bean
    如果不为null,则调用postProcessAfterInitialization后置方法
  4. 实例化bean
  5. 如果有则调用MergedBeanDefinitionPostProcessorpostProcessMergedBeanDefinition方法
  6. 填充bean属性
  7. 如果有则调用BeanNameAwaresetBeanName方法
  8. 如果有则调用BeanClassLoaderAwaresetBeanClassLoader方法
  9. 如果有则调用BeanFactoryAwaresetBeanFactory方法
  10. 如果有则调用BeanPostProcessorpostProcessBeforeInitialization前置方法
  11. bean的初始化
  12. 如果有则调用InitializingBeanafterPropertiesSet方法
  13. 如果有则调用BeanPostProcessorpostProcessAfterInitialization后置方法
  14. 如果有则调用DestructionAwareBeanPostProcessorrequiresDestruction方法
  15. 如果有则调用ApplicationContextAwaresetApplicationContext方法

xxAware实现原理

ApplicationContextAware为例:
其实还是利用BeanPostProcessor的能力,关键代码如下:

class ApplicationContextAwareProcessor implements BeanPostProcessor {

	@Override
	@Nullable
	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>) () -> {
				invokeAwareInterfaces(bean);
				return null;
			}, acc);
		}
		else {
                        // 通过调用这个方法
			invokeAwareInterfaces(bean);
		}

		return bean;
	}

	private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof EnvironmentAware) {
			((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
		}
		if (bean instanceof EmbeddedValueResolverAware) {
			((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
		}
		if (bean instanceof ResourceLoaderAware) {
			((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
		}
		if (bean instanceof ApplicationEventPublisherAware) {
			((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
		}
		if (bean instanceof MessageSourceAware) {
			((MessageSourceAware) bean).setMessageSource(this.applicationContext);
		}
		if (bean instanceof ApplicationContextAware) {
			((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
		}
	}

}

相关文章

微信公众号

最新文章

更多