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 ...
随机推荐
- 搭建hadoop伪集群
基础设置:jdk.ssh. 1.操作系统.环境.网络.必须软件 2.关闭防火墙 3.设置hosts映射 4.时间同步 5.安装jdk 6.设置ssh免秘钥部署配置:初始化运行:命令行使用:
- 教你如何开发一个完败Miracast的投屏新功能
手机与电视,是陪伴在我们生活最常见,陪伴最长久的智能设备.迅猛发展的移动终端与通信技术,赋予了手机更广阔多元的应用生态,大屏电视则以大视野和震撼影音,弥补了手里方寸带来的视觉局限.而今,手机的延伸 ...
- [CEOI1999]Parity Game 题解
P5937 [CEOI1999]Parity Game 洛谷P5937 P5937 [CEOI1999]Parity Game 前言: 个人感觉这道题初看想不到并查集啊!(说实话我题都没读懂,第二遍才 ...
- sendRedirect()和forward()方法的区别
sendRedirect()和forward()方法的区别 之前好像曾经整理过,但忘了放在哪里了,好像压根就没整理过,博客里也没有,故今天重新整理一下. 我们知道页面之间的跳转有两种方式:重定向与转发 ...
- SpringCloud Alibaba (四):Dubbo RPC框架
Dubbo简介 Apache Dubbo |ˈdʌbəʊ| 是一款高性能.轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现.致 ...
- Asp.Net Core Blazor之容器部署
写在前面 Docker作为开源的应用容器引擎,可以让我们很轻松的构建一个轻量级.易移植的容器,通过Docker方式进行持续交付.测试和部署,都是极为方便的,并且对于我们开发来说,最直观的优点还是解决了 ...
- Linux高并发网络编程开发——10-Linux系统编程-第10天(网络编程基础-socket)
在学习Linux高并发网络编程开发总结了笔记,并分享出来.有问题请及时联系博主:Alliswell_WP,转载请注明出处. 10-Linux系统编程-第10天(网络编程基础-socket) 在学习Li ...
- 将PDF转化为wrod
public static void CreateWord(string HtmlPath, string WordSavePath) { string inputName = HtmlPath; / ...
- Java 基础 —— Lambda 表达式
概述 阅读项目代码时,尤其是阅读一些源码时,经常会遇到 Lambda 表达式.对此之前看过相关文章,但是停留在模模糊糊的印象上.今天趁着有时间,通过一些 demo 示例,梳理一下它的用法,以备后期遗忘 ...
- Spring @Value注解使用${}进行注入(转)
原文:http://my.oschina.net/js99st/blog/632104 spring3中新增的@value注解 http://bijian1013.iteye.com/blog/202 ...