Spring與bean有關(guān)的生命周期示例詳解
前言
記得以前的時(shí)候,每次提起Spring中的bean相關(guān)的生命周期時(shí),內(nèi)心都無(wú)比的恐懼,因?yàn)楹孟裼泻芏?,自己又理不清楚:什么beanFactory啊,aware接口啊,beanPostProcessor啊,afterPropertiesSet啊,initMethod啊等等。
今天終于理清這些關(guān)系了,并且又新增了對(duì)postConstruct和lifecycle的理解。
執(zhí)行順序
- 首先是 BeanFactoryPostProcessor,它是針對(duì)所有bean的definition的,只執(zhí)行一次
下面是針對(duì)每個(gè)bean的初始
- - 實(shí)現(xiàn)了一系列aware接口的,比如BeanNameAware,ApplicationContextAware,調(diào)用其set方法
- - 執(zhí)行BeanPostProcessor的postProcessBeforeInitialization方法
- - 帶有@PostConstruct注解的方法
- - 實(shí)現(xiàn)InitializingBean接口的afterPropertiesSet方法
- - 指定的initMethod方法
- - 執(zhí)行BeanPostProcessor的postProcessAfterInitialization方法
- - 實(shí)現(xiàn)了SmartLifecycle接口的start方法(實(shí)現(xiàn)Lifecycle接口的不會(huì)自動(dòng)調(diào)用,需要顯式的調(diào)用start方法)
下面是針對(duì)每個(gè)bean的銷(xiāo)毀
- - 實(shí)現(xiàn)了SmartLifecycle接口的stop方法(實(shí)現(xiàn)Lifecycle接口的不會(huì)自動(dòng)調(diào)用,需要顯式的調(diào)用stop方法)
- - 帶有@PreDestroy注解的方法
- - 實(shí)現(xiàn)DisposableBean接口的destroy方法
- - 指定的destroyMethod方法
目前就想到這么多了,其他的麻煩在評(píng)論區(qū)留言呀~
代碼實(shí)例
bean實(shí)體類(lèi)
/**
* @date: 2020-07-22
*
* 一個(gè)簡(jiǎn)單的枚舉類(lèi)
*/
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
* 一個(gè)簡(jiǎn)單的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
* 實(shí)現(xiàn)了Lifecycle的一個(gè)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
* 實(shí)現(xiàn)了SmartLifecycle的一個(gè)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;
}
}
配置類(lèi)
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類(lèi)
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");
}
}
結(jié)果說(shuō)明
結(jié)果正如前面所說(shuō)的執(zhí)行順序一致,主要注意的就是Lifecycle接口和SmartLifecycle接口,只有實(shí)現(xiàn)了SmartLifecycle接口的bean在初始化時(shí)才會(huì)被自動(dòng)調(diào)用,而實(shí)現(xiàn)了Lifecycle接口的除非顯式調(diào)用start和stop方法才會(huì)被調(diào)用。
總結(jié)
到此這篇關(guān)于Spring與bean有關(guān)的生命周期的文章就介紹到這了,更多相關(guān)Spring與bean生命周期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用idea生成springboot程序的docker鏡像的操作指南
這篇文章給大家詳細(xì)的介紹了使用idea生成springboot程序的docker鏡像的操作指南,文中通過(guò)圖文結(jié)合給大家講解的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2023-12-12
SpringBoot動(dòng)態(tài)表操作服務(wù)的實(shí)現(xiàn)代碼
在現(xiàn)代的應(yīng)用開(kāi)發(fā)中,尤其是在數(shù)據(jù)庫(kù)設(shè)計(jì)不斷變化的情況下,動(dòng)態(tài)操作數(shù)據(jù)庫(kù)表格成為了不可或缺的一部分,在本篇文章中,我們將以一個(gè)典型的動(dòng)態(tài)表操作服務(wù)為例,詳細(xì)介紹如何在 Spring Boot 中使用 JdbcTemplate 實(shí)現(xiàn)動(dòng)態(tài)表管理,需要的朋友可以參考下2025-01-01
SpringBoot向resources下寫(xiě)文件的兩種方式
這篇文章給大家分享了兩種SpringBoot向resources下寫(xiě)文件的方式,每種方式都有詳細(xì)的代碼示例,對(duì)我們的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-08-08
SpringBoot基于SpringSecurity表單登錄和權(quán)限驗(yàn)證的示例
這篇文章主要介紹了SpringBoot基于SpringSecurity表單登錄和權(quán)限驗(yàn)證的示例。文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
IntelliJ IDEA Tomcat控制臺(tái)中文亂碼問(wèn)題的四種解決方案
這篇文章主要給大家分享了4種方法完美解決IntelliJ IDEA Tomcat控制臺(tái)中文亂碼問(wèn)題,文中有詳細(xì)的圖文介紹,對(duì)我們的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-08-08
SpringBoot集成Redis實(shí)現(xiàn)消息隊(duì)列的方法
這篇文章主要介紹了SpringBoot集成Redis實(shí)現(xiàn)消息隊(duì)列的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
Spring Boot入門(mén)(web+freemarker)
這篇文章主要介紹了Spring Boot入門(mén)(web+freemarker)的相關(guān)資料,需要的朋友可以參考下2017-06-06
SpringBoot自定義bean綁定實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot自定義bean綁定,最常見(jiàn)的配置綁定的場(chǎng)景,是在自定義的bean中通過(guò)@Value注解將某個(gè)屬性和對(duì)應(yīng)的配置綁定2022-10-10

