Spring的Bean生命周期和扩展点

引用自:Spring的Bean生命周期和扩展点-技术圈

想要把代码写好,不是一件容易的事情,自己总结了以下,一般要经过以下的步骤:顶层设计、详细设计、代码技巧、静态改造和动态改造。

想要把代码写好,不是一件容易的事情,自己总结了以下,一般要经过以下的步骤:顶层设计、详细设计、代码技巧、静态改造和动态改造。

​​​

这篇文章主要补齐了生命周期的改造。

一、生命周期

Bean 的生命周期主要为实例化、属性填充、初始化和销毁 4 个阶段,加上类加载和使用阶段,整个流程如下:

5e2aa86f2ff131b293a67b385461ff97.webp

二、Bean 的扩展

Spring 在每个阶段都提供了扩展点,扩展点可以分为两类:

  • 专用扩展点:用于单个 Bean 的扩展,定义 Bean 类时实现接口来扩展功能。

  • 通用扩展点:用于所有 Bean 的扩展,单独定义类实现接口来扩展功能。

1. 专用扩展点

Aware 接口

Aware 接口可以在属性填充的时候注入 Bean 信息或上下文等信息。

例如可以通过实现 BeanNameAware 接口将当前 Bean 的名称注入到类中。

public class OneBeanExample implements BeanNameAware {

    private String beanName;

    @Override
    public void setBeanName(String name) {
        this.beanName = name;
    }
}

Spring 提供了许多 Aware 的子接口可以使用,常用的有:

Aware接口注入依赖
BeanNameAwareBean 的名称
BeanFactoryAware当前上下文的 BeanFactory
ApplicationContextAware当前上下文的 ApplicationContext
ApplicationEventPublisherAware当前上下文的事件发布者 ApplicationEventPublisher
BeanClassLoaderAware加载 Bean 类的类加载器

InitializingBean 和 DisposableBean 接口

如果要在 Bean 初始化时添加自定义逻辑,可以实现 InitializingBean 接口。

如果要在 Bean 销毁时添加自定义逻辑,可以实现 DisposableBean 接口。

public class OneBeanExample implements InitializingBean, DisposableBean {

    @Override
    public void afterPropertiesSet() {
    // do some initialization work
    }

    @Override
    public void destroy() {
    // do some destruction work
    }
}

除了上面两个回调接口,也可以在注册 Bean 的时候指定自定义初始化和销毁方法。

@Bean 注解的 initMethod 属性指定 Bean 初始化方法,destroyMethod 属性指定 Bean 销毁方法。

public class OneBeanExample {

    public void init() {
        // do some initialization work
    }

    public void destroy() {
        // do some destruction work
    }
}

@Configuration
public class AppConfig {

    @Bean(initMethod = "init", destroyMethod = "destroy")
    public OneBeanExample oneBeanExample() {
        return new OneBeanExample();
    }
}

对应 XML 配置 <bean> 标签的 init-method 和 destroy-method 属性。

还可以使用 JDK 的 @PostConstruct 和 @PreDestroy 注解来指定初始化方法和销毁方法。

public class OneBeanExample {

    @PostConstruct
    public void init() {
        // do some initialization work
    }

    @PreDestroy
    public void destroy() {
        // do some destruction work
    }
}

前面提供的三种方式都可以定义 Bean 初始化和销毁时执行的方法。

InitializingBean 和 DisposableBean 接口会和 Spring 强耦合。

当项目中没有依赖 Spring 时,推荐使用第二种或第三种方式。

2. 通用扩展点

通用扩展点对所有 Bean 有效,需要定义单独的类来实现,主要有三个接口:

  • BeanPostProcessor 接口

  • InstantiationAwareBeanPostProcessor 接口

  • DestructionAwareBeanPostProcessor 接口

1e09e6eb04607faa35a2fdcfd3d0ff25.webp

BeanPostProcessor 接口

实现该接口可以在 Bean 初始化前后添加自定义逻辑。

@Component
public class BeanInitProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // before initialization work
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // after initialization work
        return bean;
    }
}

InstantiationAwareBeanPostProcessor 接口

实现该接口可以在 Bean 实例化前后添加自定义逻辑。

@Component
public class BeanInstanceProcessor implements InstantiationAwareBeanPostProcessor {

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        // before instantiation work
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        // after instantiation work
        return true;
    }
}

DestructionAwareBeanPostProcessor 接口

实现该接口可以在 Bean 销毁前添加自定义逻辑。

@Component
public class BeanDestroyProcessor implements DestructionAwareBeanPostProcessor {

    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        // before destruction work
    }
}

3. 生命周期扩展点示例

Bean 生命周期的 4 个阶段都支持扩展,每个阶段都可以添加自定义逻辑。

3.1 实例化

Spring 容器在这步实例化 Bean 对象。

实现 InstantiationAwareBeanPostProcessor 接口的两个扩展方法,在实例化前后添加扩展。

5efff07da7d6759c28ee05ed8b00e8a1.webp

3.2 属性填充

Spring 容器在这步填充属性,例如通过 Setter 方法注入依赖。

属性填充后通过 Aware 接口扩展来注入 Bean 信息或上下文等信息。

59c4a7ce0a14a9fd6eb0af8ae2c7c6b2.webp

3.2 初始化

Spring 容器在这步初始化 Bean。

实现 BeanPostProcessor 接口的两个扩展方法,在初始化前后添加扩展。

aa77526d3031711b4cea4e2b3fc0c083.webp

在初始化阶段,前面讲到三种方式来指定初始化方法,一般情况下使用一种就行。

如果同时使用三种,三种方式指定的方法相同,该方法只执行一次,当三种方式指定的方法不同,按图中顺序执行。

3.4 销毁

Spring 容器在这步销毁 Bean,可以释放外部资源。

实现 DestructionAwareBeanPostProcessor 接口的扩展方法,可以在销毁前添加扩展。

6b39931afb0e31dc7e3266cdaad747ba.webp

在销毁阶段,前面讲到三种方式来指定销毁方法,一般情况下使用一种就行。

如果同时使用三种,三种方式指定的方法相同,该方法只执行一次,当三种方式指定的方法不同,按图中顺序执行。

4. 生命周期扩展点顺序

Bean 的生命周期中,通用扩展点和专用扩展点,以及它们对应的方法,执行顺序如下图:

2d2bf7e7afc0ea65827b1e5101b5858a.webp

三、附录

1. 配置属性

属性描述
<bean>init-method属性基于 XML 配置容器中,指定自定义初始化方法
<bean>destroy-method属性基于 XML 配置容器中,指定自定义销毁方法

2. 常用注解

注解描述
@BeaninitMethod属性基于 Java 配置容器中,指定自定义初始化方法
@BeandestroyMethod属性基于 Java 配置容器中,指定自定义销毁方法
@PostConstruct使用 JDK 注解指定初始化执行的方法
@PreDestroy使用 JDK 注解指定销毁执行的方法

3. 示例代码

Gitee 仓库:

https://gitee.com/code_artist/spring

项目模块:

spring-ioc

示例路径:

cn.codeartist.spring.bean.life

扩展点的参考:
https://liuxi.name/blog/20161228/spring-container-extension.html
https://segmentfault.com/a/1190000023033670
https://potoyang.gitbook.io/spring-in-action-v4/di-3-zhang-gao-ji-zhuang-pei/untitled-2/untitled
https://cxybb.com/article/peerless_fu/107621804
https://www.cxybb.com/article/knknknkn8023/107130806
http://javajun.net/posts/39850/

生命周期的思考:
https://juejin.cn/post/6844903974361907213
https://www.cnblogs.com/javazhiyin/p/10905294.html

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring框架提供了对Bean的生命周期管理。在Spring源码中,Bean的生命周期由两个关键接口定义:BeanFactory和BeanPostProcessor。 BeanFactory是Spring的核心接口之一,它负责管理所有的Bean,并负责实例化、配置和管理它们的整个生命周期BeanFactory接口定义了许多方法,如getBean()和registerBeanDefinition(),用于获取和注册Bean。 BeanPostProcessor是另一个重要的接口,它定义了在Bean初始化的不同阶段可以插入自定义逻辑的扩展。通过实现BeanPostProcessor接口,开发人员可以在Bean的实例化、初始化和销毁等阶段插入自己的逻辑。BeanPostProcessor接口中定义了两个方法:postProcessBeforeInitialization()和postProcessAfterInitialization()。 在Spring的源码中,Bean的生命周期主要涉及以下几个重要的类和方法: 1. DefaultListableBeanFactory类:此类实现了BeanFactory接口,是Spring容器的核心实现类之一。它负责读取Bean的定义信息,并根据这些定义信息创建和管理Bean。 2. AbstractAutowireCapableBeanFactory类:此类是DefaultListableBeanFactory的子类,它提供了Bean的自动装配功能。它包含了Bean的实例化、属性注入、初始化和销毁等关键步骤。 3. AnnotationConfigApplicationContext类:此类是通过注解配置来创建Spring容器的一种方式。它根据指定的配置类,扫描注解并完成Bean的初始化和管理。 4. BeanDefinition类:此类定义了Bean的配置信息,包括Bean的类名、属性值和依赖关系等。在Bean的生命周期中,BeanDefinition起到了重要的作用。 以上只是Spring Bean生命周期源码的一部分,如果你对Spring Bean生命周期的源码感兴趣,建议你阅读Spring源码以获得更详细的了解。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值