侧边栏壁纸
博主头像
再见理想博主等级

只争朝夕,不负韶华

  • 累计撰写 112 篇文章
  • 累计创建 64 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

Spring Bean 的生命周期及扩展点

再见理想
2022-05-27 / 0 评论 / 0 点赞 / 433 阅读 / 1,027 字

一,概述

bean的生命周期主要有如下几个步骤:

  • 实例化阶段Instantiation;
  • 填充属性;
  • 初始化阶段Initialization;
  • 通过IOC容器使用bean;
  • 销毁阶段destroy()

调用时机:
-> refresh()
-> finishBeanFactoryInitialization(beanFactory)
-> beanFactory.preInstantiateSingletons()
-> getBean()
-> doGetBean()
-> createBean()
-> doCreateBean()

二,扩展点

扩展点可分为影响多个Bean和影响单个Bean:

  1. 影响多个 bean
    1. InstantiationAwareBeanPostProcessor
    2. BeanPostProcessor
  2. 影响单个Bean
    1. Aware
    2. @PostConstruct
    3. InitializingBean#afterPropertiesSet
    4. init-method
    5. @PreDestroy
    6. DisposableBean#destroy

2.1,实例化阶段扩展点

2.1.1,InstantiationAwareBeanPostProcessor

作用在实例化过程前后的后置处理器,是BeanPostProcessor的子接口
实例化前执行:postProcessBeforeInstantiation
实例化后执行:postProcessAfterInstantiation

2.2,初始化阶段扩展点

2.2.1,Aware

作用:让我们能够拿到 Spring容器中的一些资源。基本都能够见名知意,Aware之前的名字就是可以拿到什么资源,例如 BeanNameAware 可以拿到BeanName,以此类推。
调用时机:所有的 Aware 方法都是在初始化阶段之前调用的!
Aware系列接口的共性:

  • 都以 Aware 结尾;
  • 都是 Aware 接口的子接口;
  • 接口内均定义了一个 set 方法;

Aware分类(按顺序执行):

  • Aware Group1
    • BeanNameAware
    • BeanClassLoaderAware
    • BeanFactoryAware
  • Aware Group2
    • EnvironmentAware
    • EmbeddedValueResolverAware
    • ApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware)

2.2.2,BeanPostProcessor

作用在初始化过程前后的后置处理器
初始化前执行:postProcessBeforeInitialization
初始化后执行:postProcessAfterInitialization

2.2.3,@PostConstruct

@PostConstruct 是 Java 的注解, 用来修饰方法,标记在项目启动的时候执行这个方法,一般用来执行某些初始化操作比如全局配置。@PostConstruct 注解的方法会在构造函数之后执行,Servlet 的init()方法之前执行。

@PostConstruct 和 @PreDestroy 是两个作用于Servlet生命周期的注解, 被这两个注解修饰的方法可以保证在整个 Servlet 生命周期只被执行一次,即使 Web 容器在其内部中多次实例化该方法所在的 bean。

2.2.4,InitializingBean#afterPropertiesSet

InitializingBean 是 Spring 提供的拓展性接口,InitializingBean 接口为 bean 提供了属性初始化后的处理方法,它只有一个 afterPropertiesSet 方法。

2.2.5,init-method

初始化bean的时候执行,可以针对某个具体的bean进行配置。

实现 InitializingBean 或配置 init-method 均可参与bean初始化流程。

实现一:xml 配置

<bean id="TestBean" class="xxx.TestBean" init-method="init"/> 

实现二:@Bean 注解配置

@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")

2.3,销毁阶段扩展点

允许容器销毁该 bean 时获得一次回调,在 Servlet 的 destroy() 方法之前执行,一般用来释放 bean 所持有的资源。
实现方式一:在方法上添加 @PreDestroy 注解
实现方式二:实现 DisposableBean#destroy

2.4,执行时机

→ 构造方法
→ postProcessBeforeInstantiation
→ postProcessAfterInstantiation
→ Aware
→ postProcessBeforeInitialization
→ @PostConstruct
→ InitializingBean#afterPropertiesSet
→ init-method
→ postProcessAfterInitialization
→ @PreDestroy
→ DisposableBean#destroy

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.util.StringValueResolver;

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

@Component
public class MyInitializingBean implements InitializingBean, BeanNameAware,
        BeanClassLoaderAware, BeanFactoryAware,
        EnvironmentAware, EmbeddedValueResolverAware,
        ApplicationContextAware,DisposableBean {

    public MyInitializingBean() {
        System.out.println("构造方法执行...");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet 方法执行...");
    }

    @PostConstruct
    public void postConstruct() {
        System.out.println("@PostConstruct 方法执行...");
    }

    @PreDestroy
    public void PreDestroy(){
        System.out.println("@PreDestroy 方法执行...");
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("setBeanName 方法执行...");
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("setBeanClassLoader 方法执行...");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("setBeanFactory 方法执行...");
    }

    @Override
    public void setEmbeddedValueResolver(StringValueResolver stringValueResolver) {
        System.out.println("setEmbeddedValueResolver 方法执行...");
    }

    @Override
    public void setEnvironment(Environment environment) {
        System.out.println("setEnvironment 方法执行...");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("setApplicationContext 方法执行...");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean#destroy 方法执行...");
    }
}

执行结果:

三,流程图

0

评论区