探索Spring系列(一)Spring容器和Bean的生命週期

前言

不知不覺畢業已經三年有餘,前面的時間一直忙於工做上的事情,最近稍微有點空閒時間,就準備梳理下本身的知識體系,發以爲本身的知識體系非常混亂和不足,正巧手中有一些書籍,藉此機會好好學習和梳理一番,也但願本身的一點小小記錄能分享給各位,帶給你們一些收穫。java

一:Spring容器

Spring容器負責建立,管理對象,對象的整個生命週期都是由容器(container)負責的,下面是Spring中容器的接口的實現類spring

咱們在開發中接觸和使用最多的就是其中的基於註解的配置類的AnnotationConfigWebApplicationContext上下文,和基於xml配置的XmlWebApplicationContext上下文,固然Spring容器的還要一個重要的功能DI(依賴注入)這個功能我將在下個章節學習

二:Bean的生命週期

瞭解Bean的生命週期,有助於咱們理解Bean在容器的運做過程,什麼時候建立,什麼時候調用,什麼時候銷燬, spring對Bean實例化過程主要有如下幾個階段:

1:spring對bean進行實例化
2:spring將值和bean的引用注入到bean的對應屬性中
3:若是bean實現了BeanNameAware接口,Spring將bean的ID傳遞給setBeanName()方法
4:若是Bean實現了BeanFactoryAware接口,Spring將調用setBeanFactory()方法,將BeanFactory容器實例傳入
5:若是bean實現了ApplicationContextAware接口,Spring將調用setApplicationContext()方法,將bean所在的應用上下文的引用傳遞進來
6:若是bean實現了BeanPostProcessor接口,Spring將調用它的postProcessorBeforeInitialization()q前置處理方法
7:若是bean實現了InitializingBean接口,Spring將調用它們的afterPropertiesSet()方方法,相似的若是bean使用了init-method聲明瞭初始化方法,該方法也會被調用
8:若是bean實現了BeanPostProcessor接口,Spring將調用它們的postProcessorAfterInitialization()後置處理方法
9:此時bean已經準備就虛了,能夠被應用程序使用了,它們將一直駐留在應用程序上下文中,直到該應用上下文被銷燬
10:若是bean實現了DisposableBean接口,Spring將調用它的destroy()接口方法,一樣,若是bean使用了destroy-method聲明瞭銷燬方法,該方法也會被調用bash

下面咱們實際寫代碼測試一下

首先咱們定義一個實體類而且實現eanNameAware, BeanFactoryAware,ApplicationContextAware, InitializingBean, BeanPostProcessor, DisposableBean接口重寫父類的方法app

package com.lly.springtest1.entity;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * @ClassName GirlFriendEntity
 * @Description bean實體類
 * @Author lly
 * @Date 2019/1/16
 * @Version 1.0
 **/
@Slf4j
public class GirlFriendEntity implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {

    private String name;


    public GirlFriendEntity() {
        log.info("調用GirlFriendEntity的無參數構造器方法");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        log.info("BeanFactoryAware調用setBeanFactory方法將BeanFactory實例傳入");
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        log.info("對name屬性進行賦值");
        this.name = name;
    }

    @Override
    public void setBeanName(String s) {
        log.info("BeanNameAware調用setBeanName方法,將bean的name注入");
    }

    @Override
    public void destroy() throws Exception {
        log.info("DisposableBean調用destroy方法");

    }

    @Override
    public void afterPropertiesSet() throws Exception {

        log.info("InitializingBean調用afterPropertiesSet方法");
    }

    //自定義的初始化方法
    @PostConstruct
    public void myInit() {
        log.info("調用自定義的init方法");
    }

    //自定義銷燬方法
    @PreDestroy
    public void myDestroy() {
        log.info("調用自定義的destroy方法");
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.info("調用ApplicationContext方法的setApplicationContext注入上下文");
    }
}

複製代碼

接着咱們來定義個繼承BeanPostProcessor的類來觀察ide

package com.lly.springtest1.entity;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * @ClassName MyBeanPostProcessor
 * @Description
 * @Author lly
 * @Date 2019/1/16
 * @Version 1.0
 **/
@Slf4j
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean.getClass() == GirlFriendEntity.class) {
            log.info("BeanPostProcessor調用postProcessBeforeInitialization");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean.getClass() == GirlFriendEntity.class) {
            log.info("BeanPostProcessor調用postProcessAfterInitialization");
        }
        return bean;
    }

}

複製代碼

而後啓動容器看看bean初始化的具體流程post

package com.lly.springtest1.entity;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @ClassName Test
 * @Description 
 * @Author lly
 * @Date 2019/1/16
 * @Version 1.0
 **/
@Configuration
public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Test.class);
        context.close();
    }

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

    @Bean
    public GirlFriendEntity getGirl() {
        GirlFriendEntity girl = new GirlFriendEntity();
        girl.setName("穎寶");
        return girl;
    }
}

複製代碼

打印結果以下學習

咱們能夠清晰看到bean的整個生命週期

另外關於自定義初始化和銷燬的方法除了有上述的註解方式,還可使用這種方式,效果是同樣

相關文章
相關標籤/搜索