[深入學習]Spring Bean的生命周期(一)

Spring Bean的生命周期指的是Bean從創(chuàng)建到初始化再到銷毀的過程,這個過程由IOC容器管理。
一個完成的生命周期后續(xù)會記錄,這里我們主要記錄一些和Bean生命周期相關的細節(jié)。

  • Bean的初始化和銷毀(三種方式)
    1. @Bean
    2. InitializingBean&DisposableBean
    3. @PostContruct&@PreDestroy
  • BeanPostProcessor

@Bean

通過@Bean來注冊Bean,也可以通過它來指定初始化和銷毀方法。

新建SpringBoot項目,然后創(chuàng)建一個User類。

@Log
public class User {

    public User() {
        log.info("調用無參構造創(chuàng)建User");
    }

    public void init() {
        log.info("初始化 User");
    }

    public void destroy() {
        log.info("銷毀 User");
    }
}

然后配置類里注冊該組件,并指定初始化和銷毀方法。

@Configuration
public class WebConfig {

    @Bean(initMethod = "init", destroyMethod = "destroy")
    public User user() {
        return new User();
    }
}

其中initMethod = "init",destroyMethod = "destroy" 中的init,destroy 和User類中的init(),destroy()方法相對應。

測試在SpringBoot入口類中進行測試

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        // 返回IOC容器,使用注解配置,傳入配置類
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
        context.close();
    }
}

測試結果


由測試結果可以看出,創(chuàng)建IOC容器的時候,先調用無參構造方法,然后調用初始化方法,容器關閉的時候,調用銷毀方法。

InitializingBean&DisposableBean

除了@Bean來指定初始化,銷毀方法外,Spring 還提供了InitializingBean,DisposableBean接口,去實現接口,重寫接口中的afterPropertiesSet(),destroy()方法,來實現Bean的初始化,銷毀邏輯。

創(chuàng)建一個Bird類,實現InitializingBean, DisposableBean

@Log
public class Bird implements InitializingBean, DisposableBean {

    public Bird() {
        log.info("調用無參構造創(chuàng)建Bird");
    }

    @Override
    public void destroy() throws Exception {
        log.info("銷毀 Bird");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("初始化 Bird");
    }
}

在配置類中注冊該組件

@Configuration
public class WebConfig {

    @Bean
    public Bird bird() {
        return new Bird();
    }
}

測試在SpringBoot入口類中進行測試

@Log
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        // 返回IOC容器,使用注解配置,傳入配置類
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
        log.info("== 容器創(chuàng)建完畢 ");
        context.close();
    }
}

測試結果

image.png

@PostConstruct&@PreDestroy

還可以使用@PostConstruct,@PreDestroy來指定初始化,銷毀方法。

創(chuàng)建一個類Sweets

@Log
public class Sweets {

    public Sweets() {
        log.info("調用無參構造創(chuàng)建Sweets");
    }

    @PostConstruct
    public void init() {
        log.info("初始化 Sweets");
    }

    @PreDestroy
    public void destroy() {
        log.info("銷毀 Sweets");
    }
}

在配置文件中注冊該組件

@Configuration
public class WebConfig {

    @Bean
    public Sweets sweets() {
        return new Sweets();
    }
}

測試在SpringBoot入口類中進行測試

@Log
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        // 返回IOC容器,使用注解配置,傳入配置類
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
        log.info("== 容器創(chuàng)建完畢 ");
        context.close();
    }
}

測試結果

image.png

BeanPostProcessor

Spring 提供了BeanPostProcessor 接口,俗稱Bean后置通知處理器,它提供了兩個方法postProcessBeforeInitialization()和postProcessAfterInitialization(),其中postProcessBeforeInitialization()在組織初始化之前調用,postProcessAfterInitialization()在組件初始化之后調用。兩個方法都傳入兩個參數:

  1. Object bean 當前組件對象
  2. String beanName 組件名稱

定義一個組件對象MyBeanPostProcessor,實現BeanPostProcessor

@Log
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        log.info(beanName + " == 初始化之前調用");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        log.info(beanName + " === 初始化之后調用");
        return bean;
    }
}

在配置文件中注冊該組件

@Configuration
public class WebConfig {

    @Bean
    public Sweets sweets() {
        return new Sweets();
    }

    @Bean(initMethod = "init", destroyMethod = "destroy")
    public User user() {
        return new User();
    }

    @Bean
    public Bird bird() {
        return new Bird();
    }

    @Bean
    public MyBeanPostProcessor myBeanPostProcessor() {
        return new MyBeanPostProcessor();
    }
}

測試在SpringBoot入口類中進行測試

@Log
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        // 返回IOC容器,使用注解配置,傳入配置類
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
        log.info("== 容器創(chuàng)建完畢 ");
        context.close();
    }
}

測試結果

image.png

代碼地址:
https://github.com/lbshold/springboot/tree/master/Spring-Register-Bean

參考文章:
https://mrbird.cc/Spring-Bean-Lifecycle.html
https://www.cnblogs.com/zrtqsk/p/3735273.html

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 本來是準備看一看Spring源碼的。然后在知乎上看到來一個帖子,說有一群**自己連Spring官方文檔都沒有完全讀...
    此魚不得水閱讀 7,044評論 4 21
  • 參考W3C Spring教程 Spring致力于J2EE應用的各種解決方案,而不僅僅專注于某一層解決方案??梢哉fS...
    王偵閱讀 1,235評論 0 6
  • 文章作者:Tyan博客:noahsnail.com | CSDN | 簡書 3.6 Customizing the...
    SnailTyan閱讀 929評論 0 3
  • 本文章主要圍繞bean的生命周期來進行講解,比如bean的實例化之后可以做什么,還有bean銷毀之前該做什么 1....
    Mrsunup閱讀 755評論 0 0
  • 在 Spring 中,我們可以從兩個層面定義 Bean 的生命周期: Bean 的作用范圍。 實例化 Bean 時...
    deniro閱讀 2,716評論 0 8

友情鏈接更多精彩內容