Spring中与bean有关的生命周期
前言
记得以前的时候,每次提起Spring中的bean相关的生命周期时,内心都无比的恐惧,因为好像有很多,自己又理不清楚,然后看网上的帖子,好像都是那么一套,什么beanFactory啊,aware接口啊,beanPostProcessor啊,afterPropertiesSet啊,initMethod啊等等。
今天终于理清这些关系了,并且又新增了对postConstruct和lifecycle的理解。
执行顺序
- 首先是 BeanFactoryPostProcessor,它是针对所有bean的definition的,只执行一次
下面是针对每个bean的初始
- 其次是一系列实现了aware接口的,比如BeanNameAware,ApplicationContextAware,调用其set方法
- 然后执行BeanPostProcessor的postProcessBeforeInitialization方法
- 带有@PostConstruct注解的方法
- 实现InitializingBean接口的afterPropertiesSet方法
- 指定的initMethod方法
- 实现了SmartLifecycle接口的start方法(实现Lifecycle接口的不会自动调用,需要显式的调用start方法)
下面是针对每个bean的销毁
- 实现了SmartLifecycle接口的stop方法(实现Lifecycle接口的不会自动调用,需要显式的调用stop方法)
- 带有@PreDestroy注解的方法
- 实现DisposableBean接口的destroy方法
- 指定的destroyMethod方法
目前就想到这么多了,其他的麻烦在评论区留言呀~
代码实例
bean实体类
/**
* @date: 2020-07-22
*
* 一个简单的枚举类
*/
public enum BeanType {
NORMAL, LIFECYCLE, SMART_LIFECYCLE;
}
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* @author: lihui
* @date: 2020-07-22
* 一个简单的bean
*/
@Slf4j
public class NormalBean implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {
private BeanType beanType;
public NormalBean() {
this(BeanType.NORMAL);
}
public NormalBean(BeanType beanType) {
this.beanType = beanType;
}
@PostConstruct
public void postConstruct() {
log.info("{}, postConstruct", beanType);
}
@Override
public void afterPropertiesSet() throws Exception {
log.info("{}, afterPropertiesSet", beanType);
}
public void initMethod() {
log.info("{}, initMethod", beanType);
}
@PreDestroy
public void preDestroy() {
log.info("{}, preDestroy", beanType);
}
@Override
public void destroy() throws Exception {
log.info("{}, destroy", beanType);
}
public void destroyMethod() {
log.info("{}, destroyMethod", beanType);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
log.info("setApplicationContext, applicationContext : {}", applicationContext);
}
@Override
public void setBeanName(String name) {
log.info("setBeanName, bean name : {}", name);
}
}
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.Lifecycle;
/**
* @author: lihui
* @date: 2020-07-22
* 实现了Lifecycle的一个bean
*/
@Slf4j
public class LifecycleBean extends NormalBean implements Lifecycle {
private volatile boolean running = false;
public LifecycleBean() {
super(BeanType.LIFECYCLE);
}
@Override
public void start() {
log.info("start");
running = true;
}
@Override
public void stop() {
log.info("stop");
running = false;
}
@Override
public boolean isRunning() {
return running;
}
}
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.SmartLifecycle;
/**
* @author: lihui
* @date: 2020-07-22
* 实现了SmartLifecycle的一个bean
*/
@Slf4j
public class SmartLifecycleBean extends NormalBean implements SmartLifecycle {
private volatile boolean running = false;
public SmartLifecycleBean() {
super(BeanType.SMART_LIFECYCLE);
}
@Override
public void start() {
log.info("start");
running = true;
}
@Override
public void stop() {
log.info("stop");
running = false;
}
@Override
public boolean isRunning() {
return running;
}
}
配置类
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
/**
* @author: lihui
* @date: 2020-07-25
*/
@Slf4j
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
log.info("postProcessBeanFactory, beanFactory:{}", beanFactory);
}
}
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* @author: lihui
* @date: 2020-07-25
*/
@Slf4j
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
log.info("postProcessBeforeInitialization, bean:{}", beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
log.info("postProcessAfterInitialization, bean:{}", beanName);
return bean;
}
}
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.SmartLifecycle;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author: lihui
* @date: 2020-07-22
*/
@Configuration
@Slf4j
public class Config {
@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
public NormalBean normalBean() {
return new NormalBean();
}
@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
public LifecycleBean lifecycleBean() {
return new LifecycleBean();
}
@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
public SmartLifecycle smartLifecycle() {
return new SmartLifecycleBean();
}
@Bean
public static MyBeanFactoryPostProcessor myBeanFactoryPostProcessor() {
return new MyBeanFactoryPostProcessor();
}
@Bean
public static MyBeanPostProcessor myBeanPostProcessor() {
return new MyBeanPostProcessor();
}
}
Main类
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @author: lihui
* @date: 2020-07-22
*/
@Slf4j
public class Main {
public static void main(String[] args) throws InterruptedException {
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
ctx.registerShutdownHook();
Thread.sleep(5000);
log.info("line ----------------------------- line");
ctx.start();
ctx.stop();
log.info("line ----------------------------- line");
}
}
结果说明
结果正如前面所说的执行顺序一致,主要注意的就是Lifecycle接口和SmartLifecycle接口,只有实现了SmartLifecycle接口的bean在初始化时才会被自动调用,而实现了Lifecycle接口的除非显式调用start和stop方法才会被调用。
502 2020-07-26 23:43:41.808 [main] INFO c.e.d.s.a.i.l.MyBeanFactoryPostProcessor - postProcessBeanFactory, beanFactory:org.springframework.beans.factory.support.DefaultListableBeanFactory@55ca8de8: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,config,normalBean,lifecycleBean,smartLifecycle,myBeanFactoryPostProcessor,myBeanPostProcessor]; root of factory hierarchy
520 2020-07-26 23:43:41.826 [main] INFO c.e.d.s.a.i.l.MyBeanPostProcessor - postProcessBeforeInitialization, bean:config
520 2020-07-26 23:43:41.826 [main] INFO c.e.d.s.a.i.l.MyBeanPostProcessor - postProcessAfterInitialization, bean:config
536 2020-07-26 23:43:41.842 [main] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - setBeanName, bean name : normalBean
536 2020-07-26 23:43:41.842 [main] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - setApplicationContext, applicationContext : org.springframework.context.annotation.AnnotationConfigApplicationContext@7cd62f43, started on Sun Jul 26 23:43:41 CST 2020
536 2020-07-26 23:43:41.842 [main] INFO c.e.d.s.a.i.l.MyBeanPostProcessor - postProcessBeforeInitialization, bean:normalBean
536 2020-07-26 23:43:41.842 [main] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - NORMAL, postConstruct
536 2020-07-26 23:43:41.842 [main] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - NORMAL, afterPropertiesSet
536 2020-07-26 23:43:41.842 [main] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - NORMAL, initMethod
537 2020-07-26 23:43:41.843 [main] INFO c.e.d.s.a.i.l.MyBeanPostProcessor - postProcessAfterInitialization, bean:normalBean
538 2020-07-26 23:43:41.844 [main] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - setBeanName, bean name : lifecycleBean
538 2020-07-26 23:43:41.844 [main] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - setApplicationContext, applicationContext : org.springframework.context.annotation.AnnotationConfigApplicationContext@7cd62f43, started on Sun Jul 26 23:43:41 CST 2020
538 2020-07-26 23:43:41.844 [main] INFO c.e.d.s.a.i.l.MyBeanPostProcessor - postProcessBeforeInitialization, bean:lifecycleBean
538 2020-07-26 23:43:41.844 [main] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - LIFECYCLE, postConstruct
540 2020-07-26 23:43:41.846 [main] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - LIFECYCLE, afterPropertiesSet
540 2020-07-26 23:43:41.846 [main] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - LIFECYCLE, initMethod
540 2020-07-26 23:43:41.846 [main] INFO c.e.d.s.a.i.l.MyBeanPostProcessor - postProcessAfterInitialization, bean:lifecycleBean
541 2020-07-26 23:43:41.847 [main] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - setBeanName, bean name : smartLifecycle
541 2020-07-26 23:43:41.847 [main] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - setApplicationContext, applicationContext : org.springframework.context.annotation.AnnotationConfigApplicationContext@7cd62f43, started on Sun Jul 26 23:43:41 CST 2020
541 2020-07-26 23:43:41.847 [main] INFO c.e.d.s.a.i.l.MyBeanPostProcessor - postProcessBeforeInitialization, bean:smartLifecycle
541 2020-07-26 23:43:41.847 [main] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - SMART_LIFECYCLE, postConstruct
541 2020-07-26 23:43:41.847 [main] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - SMART_LIFECYCLE, afterPropertiesSet
541 2020-07-26 23:43:41.847 [main] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - SMART_LIFECYCLE, initMethod
541 2020-07-26 23:43:41.847 [main] INFO c.e.d.s.a.i.l.MyBeanPostProcessor - postProcessAfterInitialization, bean:smartLifecycle
550 2020-07-26 23:43:41.856 [main] INFO c.e.d.s.a.i.l.SmartLifecycleBean - start
5562 2020-07-26 23:43:46.868 [main] INFO c.e.d.s.a.ioc.lifecycle.Main - line ----------------------------- line
5563 2020-07-26 23:43:46.869 [main] INFO c.e.d.s.a.i.lifecycle.LifecycleBean - start
5566 2020-07-26 23:43:46.872 [main] INFO c.e.d.s.a.i.l.SmartLifecycleBean - stop
5566 2020-07-26 23:43:46.872 [main] INFO c.e.d.s.a.i.lifecycle.LifecycleBean - stop
5566 2020-07-26 23:43:46.872 [main] INFO c.e.d.s.a.ioc.lifecycle.Main - line ----------------------------- line
5576 2020-07-26 23:43:46.882 [SpringContextShutdownHook] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - SMART_LIFECYCLE, preDestroy
5576 2020-07-26 23:43:46.882 [SpringContextShutdownHook] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - SMART_LIFECYCLE, destroy
5576 2020-07-26 23:43:46.882 [SpringContextShutdownHook] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - SMART_LIFECYCLE, destroyMethod
5576 2020-07-26 23:43:46.882 [SpringContextShutdownHook] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - LIFECYCLE, preDestroy
5576 2020-07-26 23:43:46.882 [SpringContextShutdownHook] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - LIFECYCLE, destroy
5577 2020-07-26 23:43:46.883 [SpringContextShutdownHook] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - LIFECYCLE, destroyMethod
5577 2020-07-26 23:43:46.883 [SpringContextShutdownHook] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - NORMAL, preDestroy
5577 2020-07-26 23:43:46.883 [SpringContextShutdownHook] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - NORMAL, destroy
5577 2020-07-26 23:43:46.883 [SpringContextShutdownHook] INFO c.e.d.s.a.ioc.lifecycle.NormalBean - NORMAL, destroyMethod
Spring中与bean有关的生命周期的更多相关文章
- 【spring mvc】application context中【bean】的生命周期
生命周期过程 主要分为四部分: 一.实例化 1. 当调用者通过 getBean( name )向 容器寻找Bean 时,如果容器注册了org.springframework.beans.factory ...
- Spring中的实例生成方式及其生命周期
三种实例化bean的方式1.使用类构造器实例化 <!-- 使用类构造器实例化,class属性表示要使用的类的全限定名 --> <bean id="userDao1" ...
- spring Bean的完整生命周期
spring 容器中的bean的完整生命周期一共分为十一步完成. 1.bean对象的实例化 2.封装属性,也就是设置properties中的属性值 3.如果bean实现了BeanNameAware,则 ...
- 【Spring】Spring中的Bean - 4、Bean的生命周期
Bean的生命周期 简单记录-Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)-Spring中的Bean 了解Spring中Bean的生命周期有何意义? 了解Sp ...
- Spring 了解Bean的一生(生命周期)
转载 https://blog.csdn.net/w_linux/article/details/80086950 该篇博客就来了解IoC容器下Bean的一生吧,也可以理解为bean的生命周期. ## ...
- Spring IOC -bean对象的生命周期详解
生命周期执行的过程如下:1) spring对bean进行实例化,默认bean是单例2) spring对bean进行依赖注入3) 如果bean实现了BeanNameAware接口,spring将bean ...
- Spring Bean各阶段生命周期的介绍
一.xml方式配置bean 二.Aware接口 2.1 BeanNameAware 2.2 BeanFactoryAware 2.3 ApplicationContextAware 2.4 Aware ...
- [spring] -- bean作用域跟生命周期篇
作用域 singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的. prototype : 每次请求都会创建一个新的 bean 实例. request : 每一次HT ...
- spring bean 容器的生命周期是什么样的?
spring bean 容器的生命周期流程如下: 1.Spring 容器根据配置中的 bean 定义中实例化 bean. 2.Spring 使用依赖注入填充所有属性,如 bean 中所定义的配置. 3 ...
随机推荐
- HTML5实现DTMF(电话拨号按键信号)解码、编码,代码简单易于移植
目录 一.前言 1.1 HTML5实现DTMF的一些动机 1.2 一些有效场景 (1) 10086 (2) 软电话 (3) 小玩具 二.DTMF频率按键对照表 三.DTMF信号解码 得到按键值 3.1 ...
- 二.2vueadmin-template反向代理/路由配置,idc增查删
一.反向代理: (1)F:\devops\data\web\vueAdmin-template\config\index.js ---让别人也能访问我的vue前端 host: '0.0.0.0', ( ...
- Java 从入门到进阶之路(二十八)
在之前的文章我们都是通过 Java 在内存中应用,本章开始我们来看一下 Java 在系统文件(硬盘)上的操作. 系统文件就是我们电脑中的文件,简单来说就是像 Windows 系统中 C D E 等各类 ...
- Oracle IO性能测试
Oracle IO性能测试 前言 最近发生了迁移测试库后(单节点迁移RAC)因为IO性能问题导致迁移后性能非常差的问题. 原本想在创建ASM磁盘组之前用Orion做测试,但是忘了做就没做结果出了这档子 ...
- 逻辑式编程语言极简实现(使用C#) - 4. 代码实现(完结)
本文是本系列的完结篇.本系列前面的文章: 逻辑式编程语言极简实现(使用C#) - 1. 逻辑式编程语言介绍 逻辑式编程语言极简实现(使用C#) - 2. 一道逻辑题:谁是凶手 逻辑式编程语言极简实现( ...
- day56 js收尾,jQuery前戏
目录 一.原生js事件绑定 1 开关灯案例 2 input框获取焦点,失去焦点案例 3 实现展示当前时间,定时功能 4 省市联动 二.jQuery入门 1 jQuery的两种导入方式 1.1 直接下载 ...
- day18 装饰器(下)+迭代器+生成器
目录 一.有参装饰器 1 前提 2 如何使用有参装饰器 3 有参装饰器模板 4 修正装饰器 二.迭代器 1 什么是迭代器 2 为什么要有迭代器 3 如何用迭代器 3.1 可迭代对象 3.2 可迭代对象 ...
- day15 名称空间与作用域
目录 一.参数补充 1 命名关键字参数(了解) 二.名称空间 1.内置名称空间 2.全局名称空间 3.局部名称空间 4.名称空间的加载与销毁顺序 三.作用域 一.参数补充 1 命名关键字参数(了解) ...
- 管理用户和组 、 tar备份与恢复 、 cron计划任务-云计算学习(4)
配置用户和组账号 问题 本例要求创建下列用户.组以及组的成员关系: 新建用户 alex,其用户ID为3456,密码是flectrag 创建一个名为 adminuser 的组 创建一个名为 natash ...
- U盘+grub2安装centos8实战
1. U盘准备 这里的U盘也可以换成硬盘 grub2安装一直失败,怀疑U盘坏了,下面命令修复了一下 [root@host2 ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE ...