Spring的生命周期主要指创建、初始化、销毁。Bean的生命周期主要由容器进行管理,我们可以自定义bean的初始化和销毁方法,容器在bean进行到生命周期的特定时间点,来调用自定义的初始化和销毁方法。

示例代码地址:https://gitee.com/codingee/day-st/tree/sping_cyclelife/

一 初始化和销毁方式

1.1 指定初始化前方法和容器销毁后方法

init-method destory-method

  1. 单实例bean下自定义bean的初始化和销毁方法,在容器关闭时会调用当前bean的initMethod和destoryMethod方法
  2. 多实例bean 只有在调用getBean(name)时才会初始化bean,并且容器不会管理多实例bean,所以容器关闭时,不会调用bean的自定义初始化和销毁bean
package com.st.spring.cycle.bean;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;/*** \* Created with IntelliJ IDEA.* \* @author: wucj* \* @date: 2020/9/16 12:58* \* @description:* \*/
@Slf4j
public class CycleOne {public CycleOne() {log.info("{}...constructor...",this.getClass().getSimpleName());}public void init(){log.info("{}...init...",this.getClass().getSimpleName());}public void destory(){log.info("{}...destory...",this.getClass().getSimpleName());}
}

1.2 让Bean实现InitializingBean, DisposableBean 接口

package com.st.spring.cycle.bean;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;/*** \* Created with IntelliJ IDEA.* \* @author: wucj* \* @date: 2020/9/16 12:58* \* @description:* \*/
@Slf4j
public class CycleTwo implements InitializingBean, DisposableBean {public CycleTwo() {log.info("{}...constructor...", this.getClass().getSimpleName());}// 容器移除对象之后调用@Overridepublic void destroy() throws Exception {log.info("{}...destroy...", this.getClass().getSimpleName());}// 对象创建并赋值完成之后调用@Overridepublic void afterPropertiesSet() throws Exception {log.info("{}...afterPropertiesSet...", this.getClass().getSimpleName());}
}

1.3 使用jsr250规则(java规范)定义的两个注解来实现

package com.st.spring.cycle.bean;import lombok.extern.slf4j.Slf4j;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;/*** \* Created with IntelliJ IDEA.* \* @author: wucj* \* @date: 2020/9/16 12:58* \* @description:* \*/
@Slf4j
public class CycleThree{public CycleThree() {log.info("{}...constructor...", this.getClass().getSimpleName());}// 容器移除对象之后调用@PreDestroypublic void methord1(){log.info("{}...destroy...", this.getClass().getSimpleName());}// 对象创建并赋值完成之后调用@PostConstructpublic void methord2() {log.info("{}...afterPropertiesSet...", this.getClass().getSimpleName());}
}

bean注入到容器中:

package com.st.spring.cycle.config;import com.st.spring.cycle.bean.CycleOne;
import com.st.spring.cycle.bean.CycleThree;
import com.st.spring.cycle.bean.CycleTwo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;/*** \* Created with IntelliJ IDEA.* \* @author: wucj* \* @date: 2020/9/16 12:57* \* @description:* \*/
@Configuration
// 扫描指定包路径下的所有bean
@ComponentScan("com.st.spring.cycle.bean")
public class CycleConfig {/*** 自定义bean的初始化和销毁方法,在容器关闭时会调用当前bean的initMethod和destoryMethod方法* 注意1:单实例下可以调用实例的initMethod和destoryMethod方法,多实例无法调用。* 注意2:* @return*/@Bean(initMethod = "init",destroyMethod = "destory")// 多实例不能调用initMethod和destoryMetod方法// @Scope("prototype")public CycleOne cycleOne(){return new CycleOne();}@Beanpublic CycleTwo cycleTwo(){return new CycleTwo();}@Beanpublic CycleThree cycleThree(){return new CycleThree();}
}

容器启动和销毁:

package com.st.spring;import com.st.spring.cycle.config.CycleConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;/*** \* Created with IntelliJ IDEA.* \* @author: wucj* \* @date: 2020/9/16 13:01* \* @description: bean生命周期源码跟踪与学习* \*/
public class CycleConfigTest {public static void main(String[] args) {// 启动容器AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(CycleConfig.class);/*** 注意1:单实例下自定义bean的初始化和销毁方法,在容器关闭时会调用当前bean的initMethod和destoryMethod方法* 注意2:多实例bean 只有在调用getBean(name)时才会初始化bean,并且容器不会管理多实例bean,所以容器关闭时,不会调用bean的自定义初始化和销毁bean* @return*/// 关闭容器app.close();}
}

只有以上三种可以实现bean的自定义初始化和销毁调用;

二 后置处理器

后置处理器负责在初始化方法前后调用;

接口BeanPostProcessor是bean的后置处理器,在bean初始化前、后进行方法拦截;

方法1:

default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;
}

调用时机:在任何初始化方法调用之前进行后置处理工作(initMethod之前、initializingBean的afterPropertiesSet初始化之前)

方法2:

default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;
}

调用时机:在任何初始化方法调用之后进行后置处理工作(initMethod之后、initializingBean的afterPropertiesSet初始化之后)

总结:单实例bean的整个生命周期都可以进行控制;

三 容器启动及BeanPostProcessor源码分析

针对CycleConfigTest进行debug:以下所有断点位置都是源码的位置,请使用示例源码项目断点:下载

断点1:org/springframework/context/annotation/AnnotationConfigApplicationContext.java:89

refresh();

断点2:org/springframework/context/support/AbstractApplicationContext.java:551

// Instantiate all remaining (non-lazy-init) singletons. 实例化非懒加载单例beanfinishBeanFactoryInitialization(beanFactory);

断点3:org/springframework/context/support/AbstractApplicationContext.java:879

// Instantiate all remaining (non-lazy-init) singletons.beanFactory.preInstantiateSingletons();

断点4:org/springframework/beans/factory/support/DefaultListableBeanFactory.java:864

getBean(beanName);

断点5:org/springframework/beans/factory/support/DefaultListableBeanFactory.java:897

return doGetBean(name, null, null, false);

断点6:org/springframework/beans/factory/support/AbstractBeanFactory.java:201

断点7:org/springframework/beans/factory/support/AbstractBeanFactory.java:244

断点8:org/springframework/beans/factory/support/AbstractBeanFactory.java:324

return createBean(beanName, mbd, args);

断点9:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java:478

断点10:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java:516

Object beanInstance = doCreateBean(beanName, mbdToUse, args);

断点11:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java:548

断点12:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java:593

populateBean(beanName, mbd, instanceWrapper); // 属性赋值
exposedObject = initializeBean(beanName, exposedObject, mbd); // 初始化
断点13:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java:1786
// 初始化方法调用之前
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

断点14:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java:1790

// 初始化
invokeInitMethods(beanName, wrappedBean, mbd);

断点15:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java:1798

// 初始化方法调用后
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

Spring生命周期简述相关推荐

  1. spring生命周期七个过程_Spring杂文(三)Spring循环引用

    众所周知spring在默认单例的情况下是支持循环引用的 Appconfig.java类的代码 @Configurable @ComponentScan("com.sadow") p ...

  2. 【Java从0到架构师】Spring - 生命周期、代理

    生命周期.代理 bean 的生命周期 代理 业务层的一些问题 静态代理 (Static Proxy) 动态代理 (Dynamic Proxy) JDK 动态代理 - Proxy.newProxyIns ...

  3. 老司机带你从源码开始撸Spring生命周期!!!

    导读 Spring在Java Web方面有着举足轻重的地位,spring的源码设计更是被很多开发者所惊叹,巧妙的设计,精细的构思,都注定他的地位.今天陈某大言不惭的带你来从源码角度解析Spring的生 ...

  4. Spring生命周期详解

    导读 Spring中Bean的生命周期从容器的启动到停止,涉及到的源码主要是在org.springframework.context.support.AbstractApplicationContex ...

  5. Spring生命周期Bean初始化过程详解

    Spring生命周期Bean初始化过程详解 Spring 容器初始化 Spring Bean初始化 BeanFactory和FactoryBean 源码分析 Bean的实例化 preInstantia ...

  6. 详解spring生命周期的扩展点

    详解spring生命周期的扩展点,加速你追赶高手的脚步 详解spring生命周期的扩展点

  7. 【SSM - Spring篇01】spring详细概述,Spring体系结构,bean、property属性,Spring生命周期方法

    文章目录 1. Spring介绍 2. Spring体系架构 2.1 Spring核心容器(Core Container) 2.2 数据访问/集成(Data Access/Integration) 2 ...

  8. Spring 生命周期详解

    Spring 生命周期详解 一.传统JAVA bean的生命周期 使用Java关键字 new 进行Bean 的实例化,然后该Bean 就能够使用了. 一旦bean不再被使用,则由Java自动进行垃圾回 ...

  9. Spring生命周期

    学习心得 1,学习spring生命周期是很有必要的,知道bean的创建过程,在实际项目中可以解决一些启动遇到的问题 2,通过案例代码运行一遍理解会很快记住整个流程,不需要强记 3,为了节约学习成本,案 ...

最新文章

  1. 微信小程序textArea组件字数限制
  2. 【postgresql】远程连接
  3. idea去除重复代码校验
  4. 腾讯web前端招聘条件汇总
  5. 人生哲理---你值得借鉴
  6. 《福布斯》:微软的印度未来
  7. C# 自定义常用代码段
  8. 想有一个自己的WEB产品
  9. 【论文学习】Cooling-Shrinking Attack: Blinding the Tracker with Imperceptible Noises论文学习
  10. *理解JavaWeb目录结构
  11. JavaScript事件代理(事件委托)
  12. uniapp 标签技能多选 最多选三个
  13. Map与Json之间的转化
  14. 如何在idea中配置SVN
  15. 都在说测试左移和右移,只有这篇文章说明白了
  16. 刚刚,2022中国大学排行榜发布
  17. C语言数组-指定初始化器(C99)
  18. 致敬全球第一CEO杰克·韦尔奇,重温其卸任演讲
  19. 磁盘无法打开,格式是RAW
  20. 定位、相对定位、绝对定位

热门文章

  1. 网络安全原来有这么多大厂,码住!
  2. 华为麦芒5 lineageos15.1 安卓8.1
  3. PyQt5 1.0 whl文件安装 Mac OS
  4. linux egrep用法,Linux正则grep/egrep的用法
  5. 网页版打地鼠小游戏源代码,网页版打灰太狼小游戏源码
  6. 《安富莱嵌入式周报》第288期:微软推出Arm主控PC套件,WiFi信号捕获阵列,下一代雷电4技术,u-boot之父Wolfgang De离开了我们,向大神致敬
  7. 一键从Prompt到PowerPoint,斯坦福博士生自制的PPT生成神器火了
  8. python爬取中国天气网天气图标
  9. Typora设置文字颜色
  10. # Vue 中 JSON 编辑器使用