Spring学习 之Bean生命周期

怎么回答 Bean 的生命周期

实例化、属性赋值、初始化、销毁。
1、实例化: 根据配置中的 BeanDefinition 实例化 Bean。调用了Bean的构造函数。
2、属性赋值: Spring 使用依赖注入(构造器或者setter)填充所有属性。
3、初始化之前: 调用 BeanPostProcessors 实现类并注入到容器中的Bean的初始化之前方法。
4、初始化: 调用初始化方法,如果指定了初始化方法。
5、初始化之后: 调用 BeanPostProcessors 实现类并注入到容器中的Bean的初始化之后方法。
6、销毁: 当容器关闭时,调用指定的销毁方法。

生命周期流程图

在这里插入图片描述

流程简述

1、[容器级]BeanFactoryPostProcessor接口: 如果spring配置文件注册了该接口的实现类,可以在spring的bean创建之前,修改bean的定义属性。例如可以把bean的scope从singleton改为prototype。
2、[容器级]InstantiationAwareBeanPostProcessor接口: 初始化Bean之前的预处理;
3、初始化Bean
4、[容器级]InstantiationAwareBeanPostProcessor接口: 如果spring配置文件注册了该接口的实现类,Spring将调用它们的postProcessPropertyValues方法;
5、注入: Spring根据定义信息(beanDifinition)将值和引用bean注入到bean对应的属性中;
6、[Bean级]感知类名: 如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBeanName()方法;
7、[Bean级]感知容器: 如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传入进来。注:BeanFactory容器查找实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入.
8、[容器级]BeanPostProcessor: 如果bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessBeforeInitialization()方法;
9、[Bean级]InitializingBean: 如果bean实现了InitializingBean接口,Spring将调用它们的after-PropertiesSet()方法。
10、[Bean自身方法]init-method: 如果bean定义中使用指定了init-method初始化方法,该方法也会被调用;
11、[容器级]BeanPostProcessor: 如果bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessAfterInitialization()方法;
12、[容器级/后处理器]InstantiationAwareBeanPostProcessor : 如果bean实现了InstantiationAwareBeanPostProcessor 接口,Spring将调用它们的postProcessAfterInitialization()方法;

此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁;

13、[Bean级]DisposableBean: 如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。
14、[Bean自身方法]destroy-method: 如果bean定义中使用destroy-method声明了销毁方法,该方法也会被调用。

演示Spring Bean的生命周期

InstantiationAwareBeanPostProcessor接口实现:

public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    /**
     * BeanPostProcessor 接口中的方法
     * 在Bean的自定义初始化方法之前执行
     * Bean对象已经存在了
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("拦截到Bean的初始化之前:" + beanName);
        return bean;
    }
    /**
     * BeanPostProcessor接口中的方法
     * 在Bean的自定义初始化方法执行完成之后执行
     * Bean对象已经存在了
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("拦截到Bean的初始化之后:" + beanName);
        return bean;
    }
    /**
     * InstantiationAwareBeanPostProcessor中自定义的方法
     * 在方法实例化之前执行  Bean对象还没有
     */
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("拦截到Bean的实例化之前:" + beanName);
        return null;
    }
    /**
     * InstantiationAwareBeanPostProcessor中自定义的方法
     * 在方法实例化之后执行  Bean对象已经创建出来了
     */
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("拦截到Bean的实例化之后:" + beanName);
        return true;
    }
}

BeanPostProcessor 接口实现:

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("拦截到Bean的初始化之前:" + beanName);
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("拦截到Bean的初始化之后:" + beanName);
        return bean;
    }
}

业务类:

@Component
public class Person implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {
    private ApplicationContext applicationContext;
    public Person() {
        System.out.println("执行Bean构造函数进行实例化:person");
    }
    @Override
    public void setBeanName(String beanName) {
        System.out.println("setBeanName:" + beanName);
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("setApplicationContext");
        this.applicationContext = applicationContext;
    }
    @PostConstruct
    public void postConstruct() {
        System.out.println("@PostConstruct注解方法");
    }
    @PreDestroy
    public void preDestroy() {
        System.out.println("@PreDestroy注解方法");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("实现InitializingBean接口的方法afterPropertiesSet");
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("实现DisposableBean接口的方法destroy");
    }
}

测试:

public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext("org.example");
        applicationContext.close();
    }
}

运行结果:
在这里插入图片描述

BeanDefinition阶段

在 bean 的创建之前,bean 是以 BeanDefinition 的方式被描述和注册在 BeanFactory 的,这个时候虽然 bean 还没有被创建,但是 BeanFactory 中已经存有 bean 对应的 BeanDefinition 了,所以在 bean 的实例化之前,还应该有 BeanDefinition 阶段。
首先,bean 的生命周期分为 BeanDefinition 阶段和 bean 实例化阶段。(能在 bean 的生命周期中回答出 BeanDefinition 非常重要,是加分项!)

BeanDefinition 部分

  • BeanDefinition 的解析(加载 xml 配置文件、解析注解配置类、编程式注入)
  • BeanDefinition 的注册(注册到 BeanDefinitionRegistry)

bean 实例部分

  • bean 的实例化(Bean的构造函数)
  • bean 的属性赋值 + 依赖注入(处理 <bean> 中的 <property> 标签、bean 中的 @Value 、@Autowired 等自动注入的注解)
  • bean 的初始化流程
  • bean 的启动与停止
  • bean 的销毁

Bean实例化阶段

InstantiationAwareBeanPostProcessor接口实现的实例化方法之前
Bean的构造函数
InstantiationAwareBeanPostProcessor接口实现的实例化方法之后

Bean初始化阶段

Bean 对象实例化完成后,进入到初始化阶段,会进行属性赋值组件依赖注入,以及初始化阶段的方法回调
在属性赋值、依赖注入阶段,会事先收集好 Bean 中标注了依赖注入的注解( @Autowired 、@Value 、@Resource 、@Inject ),之后会借助后置处理器的初始化之前方法实现属性赋值、依赖注入。

属性赋值和依赖注入之后,会回调执行 Bean 的初始化方法,以及后置处理器的逻辑:首先会执行 Aware 相关的回调注入,之后执行后置处理器的前置回调,在后置处理器的前置方法中,会回调 bean 中标注了 @PostConstruct 注解的方法,所有的后置处理器前置回调后,会执行 InitializingBean 的 afterPropertiesSet 方法,随后是 init-method 指定的方法,等这些 bean 的初始化方法都回调完毕后,最后执行后置处理器的后置回调。

Bean销毁阶段

Bean 对象在销毁时,由 ApplicationContext 发起关闭动作。
由 BeanFactory 取出所有单实例 bean ,并逐个销毁。

先将当前 Bean 依赖的所有 Bean 都销毁。
随后回调自定义的 Bean 的销毁方法。
之后如果 bean 中有定义内部 bean 则会一并销毁。
最后销毁那些依赖了当前 bean 的 bean 也一起销毁。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值