【源码解析】Spring Bean生命周期源码解析

news/2024/10/16 18:44:20/

Spring启动核心

AbstractApplicationContext#refresh,Spring刷新容器的核心方法。最关键的就是

  • AbstractApplicationContext#invokeBeanFactoryPostProcessors,扫描Bean
  • AbstractApplicationContext#finishBeanFactoryInitialization,生成Bean。

    【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析
	@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");// Prepare this context for refreshing.prepareRefresh();// Tell the subclass to refresh the internal bean factory.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");// Invoke factory processors registered as beans in the context.invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.registerBeanPostProcessors(beanFactory);beanPostProcess.end();// Initialize message source for this context.initMessageSource();// Initialize event multicaster for this context.initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.onRefresh();// Check for listener beans and register them.registerListeners();// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();contextRefresh.end();}}}
【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析

AbstractAutowireCapableBeanFactory#doCreateBean,Spring生成Bean后会进行初始化。

  • populateBean,属性赋值
  • initializeBean,初始化
【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析
	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) {instanceWrapper = createBeanInstance(beanName, mbd, args);}// ...// Initialize the bean instance.Object exposedObject = bean;try {populateBean(beanName, mbd, instanceWrapper);exposedObject = initializeBean(beanName, exposedObject, mbd);}catch (Throwable ex) {if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;}else {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);}}// ...return exposedObject;}
【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析

在这里插入图片描述

【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析

初始化

AbstractAutowireCapableBeanFactory#initializeBean(String, Object, RootBeanDefinition),初始化。

  • invokeAwareMethods
  • applyBeanPostProcessorsBeforeInitialization
  • invokeInitMethods
  • applyBeanPostProcessorsAfterInitialization

    【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析
	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 {invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {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()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;}
【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析

触发BeanNameAware等方法

AbstractAutowireCapableBeanFactory#invokeAwareMethods,触发Aware方法,触发BeanNameAwareBeanClassLoaderAwareBeanFactoryAware

【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析

	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);}}}
【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析

触发后置处理器的postProcessBeforeInitialization方法

ApplicationContextAwareProcessor#postProcessBeforeInitializationApplicationContextAwareProcessor是后置处理器,处理额外的Aware重写方法。

	@Override@Nullablepublic 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 ||bean instanceof ApplicationStartupAware)) {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 ApplicationStartupAware) {((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());}if (bean instanceof ApplicationContextAware) {((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);}}

InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization,触发@PostConstruct标注的方法。

	@Overridepublic 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;}

InitDestroyAnnotationBeanPostProcessor#findLifecycleMetadata,寻找@PostConstruct@PreDestroy标注的方法。

	private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {if (this.lifecycleMetadataCache == null) {// Happens after deserialization, during destruction...return buildLifecycleMetadata(clazz);}// Quick check on the concurrent map first, with minimal locking.LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);if (metadata == null) {synchronized (this.lifecycleMetadataCache) {metadata = this.lifecycleMetadataCache.get(clazz);if (metadata == null) {metadata = buildLifecycleMetadata(clazz);this.lifecycleMetadataCache.put(clazz, metadata);}return metadata;}}return metadata;}private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {return this.emptyLifecycleMetadata;}List<LifecycleElement> initMethods = new ArrayList<>();List<LifecycleElement> destroyMethods = new ArrayList<>();Class<?> targetClass = clazz;do {final List<LifecycleElement> currInitMethods = new ArrayList<>();final List<LifecycleElement> currDestroyMethods = new ArrayList<>();ReflectionUtils.doWithLocalMethods(targetClass, method -> {if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {LifecycleElement element = new LifecycleElement(method);currInitMethods.add(element);if (logger.isTraceEnabled()) {logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);}}if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {currDestroyMethods.add(new LifecycleElement(method));if (logger.isTraceEnabled()) {logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);}}});initMethods.addAll(0, currInitMethods);destroyMethods.addAll(currDestroyMethods);targetClass = targetClass.getSuperclass();}while (targetClass != null && targetClass != Object.class);return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :new LifecycleMetadata(clazz, initMethods, destroyMethods));}
【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析

触发afterPropertiesSet方法

AbstractAutowireCapableBeanFactory#invokeInitMethods,触发实现了InitializingBean的方法。

	protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {boolean isInitializingBean = (bean instanceof InitializingBean);if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {if (logger.isTraceEnabled()) {logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");}if (System.getSecurityManager() != null) {try {AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {((InitializingBean) bean).afterPropertiesSet();return null;}, getAccessControlContext());}catch (PrivilegedActionException pae) {throw pae.getException();}}else {((InitializingBean) bean).afterPropertiesSet();}}if (mbd != null && bean.getClass() != NullBean.class) {String initMethodName = mbd.getInitMethodName();if (StringUtils.hasLength(initMethodName) &&!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {invokeCustomInitMethod(beanName, bean, mbd);}}}
【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析 【源码解析】Spring Bean生命周期源码解析

触发后置处理器postProcessAfterInitialization方法

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization,获取后置处理器,执行postProcessAfterInitialization

	@Overridepublic Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessAfterInitialization(result, beanName);if (current == null) {return result;}result = current;}return result;}

在这里插入图片描述


http://www.ppmy.cn/news/104062.html

相关文章

基于ChatGPT的对话生成

一、ChatGPT的对话生成 1、模型架构 ChatGPT是一种基于Transformer的神经网络模型&#xff0c;可以对输入序列和输出序列进行关注&#xff0c;并输出与输入序列相似的文本序列。在对话生成领域&#xff0c;ChatGPT模型的输入是一个由若干对话历史和当前问题组成的文本序列&am…

第一部分-基础篇-第二章:PSTN、PBX及呼叫中心业务

文章目录 序言上一篇文章&#xff1a;2.1 PSTN业务2.1.1 POTS2.1.2 商务业务2.1.3 其他增值业务 2.2 PBX业务2.2.1 呼叫转移2.2.2 同组代答 2.3 PBX与中继线2.4 IP-PBX业务2.5 呼叫中心2.5.1 什么是呼叫中心2.5.2 呼叫中心的历史2.5.3 呼叫中心的分类1.交换机类型的呼叫中心2.板…

前端面试题汇总大全二(含答案超详细,Vue,TypeScript,React,Webpack 汇总篇)-- 持续更新

前端面试题汇总大全&#xff08;含答案超详细&#xff0c;HTML,JS,CSS汇总篇&#xff09;-- 持续更新 前端面试题汇总二 五、Vue 篇1. 谈谈你对MVVM开发模式的理解&#xff1f;2. v-if 和 v-show 有什么区别&#xff1f;3. r o u t e 和 route和 route和router区别4.vue自定义…

MySQL-3-创建表、删除表、增删改、约束、索引

一、创建表 语法格式&#xff1a; create table <表名>( 字段名1 数据类型&#xff0c; 字段名2 数据类型&#xff0c; … ); 补充&#xff1a;MySQL中常见的数据类型 int 整数&#xff08;对应Java中的int&#xff09; bigint 长整型&#xff08;对应Java中的long&#…

Vue3 项目相关

vite 项目起步式 npm create vite - 1.命名项目名称- 2. 选择技术框架- 3. 进入项目文件夹 npm i 安装依赖&#xff0c;- 4. npm run dev 运行项目配置 package.json 文件 &#xff0c;使项目运行后自动再浏览器中打开。 在 dev 运行命令后添加一个 --open 即可。 "script…

第二届(2023年)中国国际培育钻石产业发展与创新大会盛大召开!

5月25-26日&#xff0c;由广东省商务厅、中国国际贸易促进委员会广东省委员会&#xff08;广东国际商会&#xff09;、广州市商务局、番禺区人民政府、广东省交易控股集团有限公司/广东省公共资源交易中心指导&#xff0c;广州钻石交易中心&#xff08;简称广钻中心&#xff09…

从汇编代码的角度去理解C++多线程编程问题

目录 1、多线程问题实例 2、理解该多线程问题的预备知识 2.1、二进制机器码和汇编代码 2.2、多线程切换与CPU时间片 2.3、多线程创建与线程函数 3、从汇编代码的角度去理解多线程问题 4、问题解决办法 5、熟悉汇编代码有哪些用处&#xff1f; 5.1、在代码中插入汇编代…

基于工业互联网的RV1126+AI安防单目/双目高清视觉分析计数仪方案

1产品简介 产品介绍 单目视觉分析计数器是信迈科技基于单目图像分析以及深度学习算法研发的一款区域统计计数器。它可以精确的识别监控区域内的物体&#xff0c;统计区域内停驻的人数/车辆等&#xff0c;也可以统计区域内进入以及离开人数。它可适用于公交车&#xff0c;大巴&…