02-spring bean的生命周期初探

Bean的生命周期

一、初始化

1.1 @Bean指定init方法

1.2 InitializingBean接口afterPropertiesSet方法

1.3 PostConstruct(JSR250规范)

二、@BeanPostProcessor后置处理器

2.1 postProcessBeforeInitialization方法

  • 在init方法之前调用

2.2 postProcessAfterInitialization方法

  • afterPropertiesSet之后调用

三、销毁

3.1 @Bean指定destroyMethod方法

  • 单实例的bean,在容器关闭时会调用destroyMethod方法,多实例bean容器关闭时不会调用销毁方法

3.2 DisposableBean接口destroy方法

3.3 PreDestroy方法(JSR250规范)

四、生命周期时序

  • 初始化,销毁和后置处理器的执行顺序

4.1 代码

@Configuration
@ComponentScan("com.intellif.ch7.processor")
public class Cap7MainConfig {

    @Bean(value = "man", initMethod = "init", destroyMethod = "destroySelf")
    public Man man() {
        return new Man("Parker", 33);
    }
}

public class Man implements DisposableBean, InitializingBean {

    private String name;
    private int age;

    public Man(String name, int age) {
        System.out.println("Man 带参构造方法执行...");
        this.name = name;
        this.age = age;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("Man 继承DisposableBean接口的destroy 方法调用");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Man 继承InitializingBean接口的afterPropertiesSet 方法调用");
    }

    public void init() {
        System.out.println("Man 类initMethod属性指定的 init 方法执行...");
    }

    public void destroySelf() {
        System.out.println("Man 类destroyMethod属性指定的 destroySelf 方法执行...");
    }

    @PostConstruct
    public void postConstruct() {
        System.out.println("Man.....PostConstruct注解指定的方法执行........");
    }

    @PreDestroy
    public void preDestroy() {
        System.out.println("Man.....PreDestroy注解指定的方法执行......");
    }

}

@Component
public class MyBeanProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //返回一个的对象(传过来的对象)
        //在初始化方法调用之前进行后置处理工作,
        //什么时候调用它: init-method=init之前调用
        System.out.println("BeanPostProcessor的postProcessBeforeInitialization....执行.." + beanName + "..." + bean);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor的postProcessAfterInitialization....执行.." + beanName + "..." + bean);
        return bean;
    }
}

@Component
public class MyMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {

    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        System.out.println("MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法执行..." + beanName);
    }

}

@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("MyInstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法执行..."+beanName);
        return null;
    }

    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("MyInstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法执行..."+beanName);
        return true;
    }

    public PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        System.out.println("MyInstantiationAwareBeanPostProcessor的PropertyDescriptor方法执行..."+beanName);
        return pvs;
    }
}

public class Ch7Test {

    @Test
    public void test01() {

        ApplicationContext app = new AnnotationConfigApplicationContext(Cap7MainConfig.class);
        System.out.println("------cut-off---------");

        ((AnnotationConfigApplicationContext) app).close();
 
    }
}

打印:(去除了多余的打印)
MyInstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法执行...man
Man 带参构造方法执行...
MyMergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法执行...man
MyInstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法执行...man
MyInstantiationAwareBeanPostProcessor的PropertyDescriptor方法执行...man
postProcessBeforeInitialization....man...Man{name='Parker', age=33}
Man.....PostConstruct方法执行........
Man afterPropertiesSet 方法调用
Man 类的 init 方法执行...
postProcessAfterInitialization....man...Man{name='Parker', age=33}
------cut-off---------
Man.....PreDestroy方法执行......
Man destroy 方法调用
Man 类的 destroySelf 方法执行...

4.2 表格

执行顺序方法生命周期阶段备注
1InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation实例化之前实例化之前
2构造方法构造方法实例化
3MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition修改bean定义信息实例化之后
4InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation实例化之后实例化之后
5InstantiationAwareBeanPostProcessor的PropertyDescriptor实例化之后实例化之后
6BeanPostProcessor的postProcessBeforeInitialization方法后置处理器,初始化之前和10对应
7JSR250规范的PostConstruct注解指定的方法初始化和11对应
8* InitializingBean接口的afterPropertiesSet方法*初始化和12对应
9++@Bean注解的initMethod属性指定的init方法++初始化和14对应
10BeanPostProcessor的postProcessAfterInitialization方法后置处理器,初始化之后和6对应
11JSR250规范的PreDestroy注解指定的方法销毁和7对应
12DisposableBean接口的destroy方法销毁和8对应
13++@Bean注解的destroyMethod属性指定的destroySelf方法++销毁和9对应
  • 这里我们看到,整体的方法其实是成对的,首先是构造方法,然后初始化方法被处理器所环绕,环绕的内部的3个初始化方法和最后的三个销毁方法成对出现并且顺序一致,最先是PostConstruct和PreDestroy,其次是InitializingBean和DisposableBean,最后是initMethod和destroyMethod,所以感觉这些扩展接口在设计的时候还是有充分的考虑的,这些顺序的一致对是良好扩展性的体现和基础。
  • 最前面的InstantiationAwareBeanPostProcessor和MergedBeanDefinitionPostProcessor接口我们在后面在具体分析,这是Spring框架本身很多注解和功能实现的关键接口。
  • 本文我们只是初步探究了Bean的生命周期中的主要方法,主要是了解其在执行上的时序关系,跟详细的分析后续会慢慢给出。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值