深入理解Spring中Bean的生命周期

Bean的執(zhí)行流程圖

Spring中Bean 的完整生命周期,在學(xué)習(xí)Spring 框架的時候,理解Spring的Bean的管理的非常重要,下圖是Spring的Bean構(gòu)造的全過程:

image

Bean 的生命周期

  1. Spring啟動,查找并加載需要被Spring管理的bean,進行Bean的實例化

  2. Bean實例化后對將Bean屬性注入值

  3. 如果Bean實現(xiàn)了BeanNameAware接口的話,Spring將調(diào)用setBeanName()方法,將Bean的id 傳進來

  4. 如果Bean實現(xiàn)了BeanFactoryAware接口的話,Spring將調(diào)用setBeanFactory()方法,將BeanFactory容器實例傳進來

  5. 如果Bean實現(xiàn)了ApplicationContextAware接口的話,Spring將調(diào)用Bean的setApplicationContext()方法,將bean所在應(yīng)用上下文引用傳進來。

  6. 如果Bean實現(xiàn)了BeanPostProcessor接口,Spring就將調(diào)用他們的BeanPostProcessor.postProcessBeforeInitialization()方法

  7. 如果Bean中方法標注注解@PostConstruct,就執(zhí)行該方法

  8. 如果Bean 實現(xiàn)了InitializingBean接口,Spring將調(diào)用他們的InitializingBean.afterPropertiesSet()方法。同時,如果bean使用init-method聲明了初始化方法,該方法也會被調(diào)用

  9. 如果Bean 實現(xiàn)了BeanPostProcessor接口,Spring就將調(diào)用他們的BeanPostProcessor.postProcessAfterInitialization()()方法。這時,Bean已經(jīng)準備創(chuàng)建完成了。他們將一直存在應(yīng)用上下文中,直到應(yīng)用上下文被銷毀。

  10. 如果Bean中方法標注注解@PreDestroy,就執(zhí)行該方法

  11. 如果bean實現(xiàn)了DisposableBean接口,Spring將調(diào)用它的destory()接口方法,同樣,如果bean使用了destory-method 聲明銷毀方法,該方法也會被調(diào)用。

代碼實例驗證Bean 的生命周期

User 類,實現(xiàn)BeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean接口

public class User implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {

    private String userName;

    public User() {
        System.out.println("User 被實例化?。。?!");
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        System.out.println("阿福聊聊編程??!");
        this.userName = userName;
    }

    public void init() {
        System.out.println("執(zhí)行initMethod方法?。?!");
    }

    @PostConstruct
    public void postContruct() {
        System.out.println("執(zhí)行@PostConstruct方法");
    }

    public void destory1() {
        System.out.println("執(zhí)行destroyMethod方法!?。?!");
    }

    @PreDestroy
    public void preDestroy() {
        System.out.println("執(zhí)行@PreDestroy 方法?。。?!");
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("執(zhí)行InitializingBean.afterPropertiesSet()");
    }

    public void destroy() throws Exception {
        System.out.println("DisposableBean.destroy()");
    }

    public void setBeanName(String name) {
        System.out.println("BeanNameAware.setBeanName()" + "--->BeanName:" + name);
    }

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryAware.setBeanFactory()");
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("ApplicationContextAware.setApplicationContext()" );
    }
}

定義后置處理器MyBeanPostProcessor,實現(xiàn)postProcessBeforeInitialization,postProcessAfterInitialization的方法

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("MyBeanPostProcessor.postProcessBeforeInitialization()--before->"+"初始化beanName:"+beanName);
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("MyBeanPostProcessor.postProcessAfterInitialization()--after-->"+"初始化beanName:"+beanName);
        return bean;
    }
}

定義MyConfigUser,將User ,MyBeanPostProcessor 注冊到Spring容器當(dāng)中,關(guān)于Bean注冊參考SpringIOC匯總

@ComponentScan(basePackages = "zfcoding.beanpostprocessor")
@Configuration
public class MyConfigUser {

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

單元測試

public class BeanProcessTest {
    @Test
    public void test(){
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MyConfigUser.class);
        User user = applicationContext.getBean(User.class);
        applicationContext.close();
    }
}

運行結(jié)果:

User 被實例化?。。。?BeanNameAware.setBeanName()--->BeanName:user
BeanFactoryAware.setBeanFactory()
ApplicationContextAware.setApplicationContext()
MyBeanPostProcessor.postProcessBeforeInitialization()--before->初始化beanName:user
執(zhí)行@PostConstruct方法
執(zhí)行InitializingBean.afterPropertiesSet()
執(zhí)行initMethod方法?。?!
執(zhí)行@PreDestroy 方法!?。?!
DisposableBean.destroy()
執(zhí)行destroyMethod方法?。。。?

文章參考:https://www.cnblogs.com/javazhiyin/p/10905294.html

以上就是Spring Bean 創(chuàng)建的全過程,完事。

我是阿福,公眾號「阿福聊編程」作者,對后端技術(shù)保持學(xué)習(xí)愛好者,我會經(jīng)常更新JAVA技術(shù)文章,在進階的路上,共勉!

歡迎大家關(guān)注我的公眾號,后臺回復(fù)666,領(lǐng)取Java全套進階實戰(zhàn)課程。

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

友情鏈接更多精彩內(nèi)容