12 Bean的生命周期

1 Bean的生命周期

bean的声明周期:

  1. 创建
  2. 初始化
  3. 销毁

我们可以自定义初始化和销毁方法,容器在bean执行到当前生命周期的时候来调用自己定义的初始化和销毁逻辑
为了演示bean声明周期,将在创建一个新的包,用于测试演示。

1.1 创建

之前已经提过:
单实例:在容器启动的时候创建
多实例:在每次获取的时候创建

1.2 初始化

单实例:对象创建完,并赋值好,调用初始化方法
多实例:对象创建完,并赋值好,调用初始化方法

1.3 销毁

单实例:容器关闭的时候执行销毁逻辑
多实例:容器不会管理这个Bean,容器不会调用销毁方法,需要自己手动调用

2 @Bean注解中指定初始化和销毁方法

@bean注解的时候介绍过一次,通过initMethoddestroyMethod指定初始化方法和销毁方法

定义一个bean

package study.wyy.spring.anno.life.bean;

/**
 * @author wyaoyao
 * @data 2020-11-23 07:49
 */
public class LifeBean {

    /**
     * 构造方法
     */
    public LifeBean() {
        System.out.println("LifeBean constructor。。。");
    }

    /**
     * 初始化方法
     */
    public void init(){
        System.out.println("LifeBean init。。。");
    }

    /**
     * 销毁方法
     */
    public void destroy(){
        System.out.println("LifeBean destroy。。。");

    }
}

使用bean注解注入容器,并指定初始化和销毁方法

package study.wyy.spring.anno.life.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import study.wyy.spring.anno.life.bean.LifeBean;

/**
 * @author wyaoyao
 * @data 2020-11-23 07:51
 */
@Configuration
public class SpringConfig {
    
    @Bean(initMethod = "init",destroyMethod = "destroy")
    public LifeBean lifeBean(){
        return new LifeBean();
    }
}

测试

@org.junit.Test
public void test01(){
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    System.out.println("ioc容器创建完成");
    context.close();
}

输出结果

LifeBean constructor。。。
LifeBean init。。。
ioc容器创建完成
LifeBean destroy。。。

上面测试的是单实例bean的生命周期
可见在单实例在容器创建完成时,就完成单实例bean的创建和初始化
那何时销毁呢—>在容器关闭的时候。

下面测试多实例bean的声明周期,使用@Scope注解

package study.wyy.spring.anno.life.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import study.wyy.spring.anno.life.bean.LifeBean;

/**
 * @author wyaoyao
 * @data 2020-11-23 07:51
 */
@Configuration
public class SpringConfig1 {

    @Bean(initMethod = "init",destroyMethod = "destroy")
    @Scope("prototype")
    public LifeBean lifeBean(){
        return new LifeBean();
    }
}

测试

 @org.junit.Test
public void test02(){
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig1.class);
    System.out.println("ioc容器创建完成");
    context.close();
}

输出

ioc容器创建完成

可见多实例的时候在创建ioc容器的时候不会创建bean

@org.junit.Test
public void test03(){
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig1.class);
    System.out.println("ioc容器创建完成");
    LifeBean bean = context.getBean(LifeBean.class);
    context.close();
}

输出

ioc容器创建完成
LifeBean constructor。。。
LifeBean init。。。

发现多实例在每次获取的时候执行创建和初始化,但是容器关闭的时候不会执行销毁逻辑

3 InitializingBean , DisposableBean

3.1 介绍

public interface InitializingBean {
	/**
	 * Invoked by a BeanFactory after it has set all bean properties supplied
	 * (and satisfied BeanFactoryAware and ApplicationContextAware).
	 * <p>This method allows the bean instance to perform initialization only
	 * possible when all bean properties have been set and to throw an
	 * exception in the event of misconfiguration.
	 * @throws Exception in the event of misconfiguration (such
	 * as failure to set an essential property) or if initialization fails.
	 */
	 // bean的属性设置完成之后执行
	 void afterPropertiesSet() throws Exception;
}
public interface DisposableBean {

	/**
	 * Invoked by a BeanFactory on destruction of a singleton.
	 * @throws Exception in case of shutdown errors.
	 * Exceptions will get logged but not rethrown to allow
	 * other beans to release their resources too.
	 */
	 // 销毁的时候执行
	void destroy() throws Exception;

}

3.2 演示

定义一个Bean实现这两个接口

package study.wyy.spring.anno.life.bean;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

/**
 * @author wyaoyao
 * @data 2020-11-23 07:49
 */
public class LifeBean2 implements InitializingBean, DisposableBean {

    /**
     * 构造方法
     */
    public LifeBean2() {
        System.out.println("LifeBean2 constructor。。。");
    }
   
    /**
     * 销毁方法
     */
    @Override
    public void destroy(){
        System.out.println("LifeBean2 destroy。。。");

    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("LifeBean2 afterPropertiesSet。。。");
    }
}

注入容器

package study.wyy.spring.anno.life.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import study.wyy.spring.anno.life.bean.LifeBean2;

/**
 * @author wyaoyao
 * @data 2020-11-23 07:51
 */
@Configuration
public class SpringConfig2 {
    @Bean
    public LifeBean2 lifeBean(){
        return new LifeBean2();
    }
}

测试


 @org.junit.Test
 public void test04(){
     AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig2.class);
     System.out.println("ioc容器创建完成");
     context.close();
 }

输出

LifeBean2 constructor。。。
LifeBean2 afterPropertiesSet。。。
ioc容器创建完成
LifeBean2 destroy。。。

测试多实例

package study.wyy.spring.anno.life.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import study.wyy.spring.anno.life.bean.LifeBean2;

/**
 * @author wyaoyao
 * @data 2020-11-23 07:51
 */
@Configuration
public class SpringConfig3 {
    @Bean
    @Scope("prototype")
    public LifeBean2 lifeBean(){
        return new LifeBean2();
    }
}

@org.junit.Test
public void test05(){
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig3.class);
    System.out.println("ioc容器创建完成");
    LifeBean2 bean = context.getBean(LifeBean2.class);
    context.close();
}
ioc容器创建完成
LifeBean2 constructor。。。
LifeBean2 afterPropertiesSet。。。

4 JSR250

  • @PostConstruct: bean创建完成并属性赋值完成的时候执行
  • @PreDestroy: 容器销毁的对象的前通知

定义一个bean

package study.wyy.spring.anno.life.bean;

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

/**
 * @author wyaoyao
 * @data 2020-11-23 08:10
 */
public class LifeBean3 {

    public LifeBean3() {
        System.out.println("LifeBean3 constructor。。。");
    }
    /**
     * 容器销毁的对象的前通知
     * @throws Exception
     */
    @PreDestroy
    public void destroy() throws Exception {
        System.out.println("LifeBean3 destroy。。。");
    }

    /**
     * bean创建完成并属性赋值完成的时候执行
     * @throws Exception
     */
    @PostConstruct
    public void afterPropertiesSet() throws Exception {
        System.out.println("LifeBean3 afterPropertiesSet。。。");
    }
}

注入容器

package study.wyy.spring.anno.life.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import study.wyy.spring.anno.life.bean.LifeBean2;
import study.wyy.spring.anno.life.bean.LifeBean3;

/**
 * @author wyaoyao
 * @data 2020-11-23 07:51
 */
@Configuration
public class SpringConfig4 {
    @Bean
    public LifeBean3 lifeBean(){
        return new LifeBean3();
    }
}

测试


@org.junit.Test
public void test06(){
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig4.class);
    System.out.println("ioc容器创建完成");
    LifeBean3 bean = context.getBean(LifeBean3.class);
    context.close();
}

输出

LifeBean3 constructor。。。
LifeBean3 afterPropertiesSet。。。
ioc容器创建完成
LifeBean3 destroy。。。

5 三者比较

上述提供的3个初始化和销毁的方式,这三个之间的顺序又是如何呢

一个Bean通过上面三个方式进行初始化

package study.wyy.spring.anno.life.config;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

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

/**
 * @author wyaoyao
 * @data 2020-11-23 08:14
 */
public class LifeBean4 implements InitializingBean, DisposableBean {

    public LifeBean4() {
        System.out.println("LifeBean4 constructor。。。");
    }


    /**
     * 销毁的时候执行
     * @throws Exception
     */
    @Override
    public void destroy() throws Exception {
        System.out.println("LifeBean4 destroy。。。");
    }

    /**
     * bean的属性设置完成之后执行
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("LifeBean4 afterPropertiesSet。。。");
    }

    @PostConstruct
    public void postConstruct(){
        System.out.println("LifeBean4 postConstruct。。。");
    }

    @PreDestroy
    public void preDestroy(){
        System.out.println("LifeBean4 preDestroy。。。");
    }

    public void init(){
        System.out.println("LifeBean4 init。。。");
    }

    public void destroyOnBean(){
        System.out.println("LifeBean4 destroyOnBean。。。");
    }
}

配置

package study.wyy.spring.anno.life.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import study.wyy.spring.anno.life.bean.LifeBean3;

/**
 * @author wyaoyao
 * @data 2020-11-23 07:51
 */
@Configuration
public class SpringConfig5 {


    @Bean(initMethod = "init",destroyMethod = "destroyOnBean")
    public LifeBean4 lifeBean(){
        return new LifeBean4();
    }
}

测试

@org.junit.Test
public void test07(){
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig5.class);
    System.out.println("ioc容器创建完成");
    LifeBean4 bean = context.getBean(LifeBean4.class);
    context.close();
}

输出

LifeBean4 constructor。。。
LifeBean4 postConstruct。。。
LifeBean4 afterPropertiesSet。。。
LifeBean4 init。。。
ioc容器创建完成
LifeBean4 preDestroy。。。
LifeBean4 destroy。。。
LifeBean4 destroyOnBean。。。

可见初始化和销毁的时候这三个顺序:

  • @postConstruct
  • InitializingBean
  • @Bean

6 BeanPostProcessor

6.1 BeanPostProcessor介绍

可以对Spring容器扫描到的Bean在初始化前后进行增强处理

public interface BeanPostProcessor {

	 /**
     *
     * @param bean : 当前的处理Bean
     * @param beanName 当前Bean的name
     * @return 可以返回当前的Bean也可以返回当前Bean的包装
     * @throws BeansException
     * 初始化(afterPropertiesSet,init-method)之前
     */
	Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
     *
     * @param bean 当前的处理Bean
     * @param beanName 当前Bean的name
     * @return 可以返回当前的Bean也可以返回当前Bean的包装
     * @throws BeansException
     * 初始化(afterPropertiesSet,init-method)之后
     */
	Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

}

6.2 BeanPostProcessor测试

只对LifeBean4类型进行增强

package study.wyy.spring.anno.life.spi;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import study.wyy.spring.anno.life.bean.LifeBean4;

/**
 * @author wyaoyao
 * @data 2020-11-23 08:21
 * BeanPostProcessor:Bean初始化前后进行增强处理
 */

public class MyBeanPostProcessor implements BeanPostProcessor {

    /**
     *
     * @param bean : 当前的处理Bean
     * @param beanName 当前Bean的name
     * @return 可以返回当前的Bean也可以返回当前Bean的包装
     * @throws BeansException
     * 初始化之前
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if(bean instanceof LifeBean4){
            // 只对LifeBean4类型进行增强
            System.out.println("BeanPostProcessor "+ beanName +"postProcessBeforeInitialization 。。。");
        }
        return bean;
    }

    /**
     *
     * @param bean 当前的处理Bean
     * @param beanName 当前Bean的name
     * @return 可以返回当前的Bean也可以返回当前Bean的包装
     * @throws BeansException
     * 初始化之后
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if(bean instanceof LifeBean4){
            // 只对LifeBean4类型进行增强
            System.out.println("BeanPostProcessor "+ beanName +"postProcessAfterInitialization 。。。");
        }
        return bean;
    }
}

配置

package study.wyy.spring.anno.life.config;

import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import study.wyy.spring.anno.life.bean.LifeBean4;
import study.wyy.spring.anno.life.spi.MyBeanPostProcessor;

/**
 * @author wyaoyao
 * @data 2020-11-23 07:51
 */
@Configuration
public class SpringConfig6 {


    @Bean(initMethod = "init",destroyMethod = "destroyOnBean")
    public LifeBean4 lifeBean(){
        return new LifeBean4();
    }
    @Bean
    public BeanPostProcessor myBeanPostProcessor(){
        return new MyBeanPostProcessor();
    }
}

测试


@org.junit.Test
public void test08(){
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig6.class);
    System.out.println("ioc容器创建完成");
    LifeBean4 bean = context.getBean(LifeBean4.class);
    context.close();
}

输出

LifeBean4 constructor。。。
BeanPostProcessor lifeBeanpostProcessBeforeInitialization 。。。
LifeBean4 postConstruct。。。
LifeBean4 afterPropertiesSet。。。
LifeBean4 init。。。
BeanPostProcessor lifeBeanpostProcessAfterInitialization 。。。
ioc容器创建完成
LifeBean4 preDestroy。。。
LifeBean4 destroy。。。
LifeBean4 destroyOnBean。。。

可以看到BeanPostProcessor的执行时机是在:构造之后,初始化方法前后执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值