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 ...
随机推荐
- node+ajax实战案例(3)
3.用户注册实现 3.1.注册用户功能的实现逻辑 1 用户在表单上输入注册信息 2 点击注册后,收集用户在表单上输入的注册信息并且发送给后台 3 后台接收用户发送过来的注册信息 4 后台需要处理数据并 ...
- Navicat15安装激活版教程
navicat15安装 一键式安装,安装包如下 链接:https://pan.baidu.com/s/1VTJmJ7ulUySWoWBu-fugiw 提取码:fz5u 先安装软件包点击安装,一直下一步 ...
- java中的四种访问权限是?
1.私有权限(private) private可以修饰数据成员,构造方法,方法成员,不能修饰类(此处指外部类,不考虑内部类).被private修饰的成员,只能在定义它们的类中使用,在其他类中不能调用. ...
- 集成Swagger在线调试
SpringBoot 是为了简化 Spring 应用的创建.运行.调试.部署等一系列问题而诞生的产物,自动装配的特性让我们可以更好的关注业务本身而不是外部的XML配置,我们只需遵循规范,引入相关的依赖 ...
- docker 容器与本机文件的拷贝操作
[把docker中容器时db002里面的my.cnf文件拷贝到根目录下] docker cp db002:/etc/mysql/my.cnf ~/root/ [把根目录下my.cnf文件拷贝到doc ...
- 写出Python中列表、元祖、字典、字符串的至少5种以上的方法
1.列表 常用方法 作用 参数 append(data) 在尾部添加数据 data-加入到列表中的数据 insert(idx,data) 在指定位置添加数据 idx-索引 data-数据 ext ...
- SpringMvc流程分析,简单源码分析
SpringMvc的请求入口:web.xml中的DispatcherServlet <servlet> <servlet-name>springServlet</serv ...
- MyBatis和Spring整合的奥秘
本篇博客源码分析基于Spring 5.1.16.RELEASE,mybatis-spring 2.0.0,较高版本的mybatis-spring源码有较大区别. Spring之所以是目前Java最受欢 ...
- 测试必备工具之抓包神器 Charles 如何抓取 https 数据包?
之前发过一篇文章讲解了Charles抓包工具的基本使用(有需要的小伙伴可以去看上一篇文章), 讲的数据包主要是http协议,大家可以看到数据包并直接显示具体详细的内容: 但是如果抓到的是https的 ...
- 读《大话设计模式》——应用工厂模式的"商场收银系统"(WinForm)
要做的是一个商场收银软件,营业员根据客户购买商品单价和数量,向客户收费.两个文本框,输入单价和数量,再用个列表框来记录商品的合计,最终用一个按钮来算出总额就可以了,还需要一个重置按钮来重新开始. 核心 ...