Spring BeanPostProcessor究竟是如何工作的?

And*_*ili 82 architecture spring spring-mvc

我正在研究Spring Core认证,我对Spring如何处理bean生命周期,特别是bean后处理器有一些疑问.

所以我有这个架构:

在此输入图像描述

这对我来说非常清楚它意味着什么:

以下步骤发生在" 加载Bean定义"阶段:

  • @Configuration类被处理和/或@Components被扫描和/或XML文件进行解析.

  • Bean定义添加到BeanFactory(每个都在其id下编入索引)

  • 调用了特殊BeanFactoryPostProcessor bean,它可以修改任何bean的定义(例如,对于property-placeholder值替换).

然后在bean创建阶段执行以下步骤:

  • 默认情况下,每个bean都会被急切地实例化(以正确的顺序创建并注入其依赖项).

  • 在依赖注入之后,每个bean经历后处理阶段,其中可以进行进一步的配置和初始化.

  • 在后处理之后,bean被完全初始化并准备好使用(由id跟踪直到上下文被销毁)

好的,这对我来说非常清楚,我也知道有两种类型的bean后处理器:

  • 初始化器:如果指示(即@PostConstruct)初始化bean.

  • 以及所有其余的:允许进行额外配置,并且可以在初始化步骤之前或之后运行

我发布这张幻灯片:

在此输入图像描述

所以我很清楚初始化器 bean后处理器是什么(它们是使用@PostContruct注释注释的方法,并且在setter方法之后立即自动调用(因此在依赖注入之后),我知道我可以使用执行一些初始化批处理(如上例所示填充缓存).

但究竟什么代表了其他bean后处理器?当我们说在初始化阶段之前或之后执行这些步骤时,我们的意思是什么?

因此我的bean被实例化并且它的依赖项被注入,因此初始化阶段就完成了(通过执行@PostContruct注释方法).在初始化阶段之前使用Bean Post处理器是什么意思?这意味着它发生在@PostContruct注释方法执行之前?这是否意味着它可能在依赖注入之前发生(在调用setter方法之前)?

当我们说它是在初始化步骤之后执行时,我们究竟是什么意思.这意味着它会在执行@PostContruct注释方法之后发生,或者是什么?

我可以很容易地想到为什么我需要一个@PostContruct注释方法,但我无法想象另一种bean后处理器的典型例子,你能告诉我一些典型的例子吗?

Mas*_*ave 40

Spring doc 使用BeanPostProcessor解释了定制bean下的BPP .BPP bean是一种特殊的bean,它在任何其他bean之前创建并与新创建的bean交互.通过这种结构,Spring可以简单地通过实现BeanPostProcessor自己来为您提供连接和自定义生命周期行为的方法.

有像自定义BPP

public class CustomBeanPostProcessor implements BeanPostProcessor {

    public CustomBeanPostProcessor() {
        System.out.println("0. Spring calls constructor");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        System.out.println(bean.getClass() + "  " + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        System.out.println(bean.getClass() + "  " + beanName);
        return bean;
    }
}
Run Code Online (Sandbox Code Playgroud)

将被调用并打印出每个创建的bean的类和bean名称.

要了解该方法如何适应bean的生命周期,以及何时调用该方法,请检查文档

postProcessBeforeInitialization(Object bean,String beanName)在任何bean初始化回调(如InitializingBean的afterPropertiesSet或自定义init方法)之前,将此BeanPostProcessor应用于给定的新bean实例.

postProcessAfterInitialization(Object bean,String beanName)在任何bean初始化回调(如InitializingBean的afterPropertiesSet或自定义init方法)之后,将此BeanPostProcessor应用于给定的新bean实例.

重要的是这一点

bean已经填充了属性值.

关于与@PostConstruct注释的关系有什么关系,这个注释是一种方便的方法来声明一个postProcessAfterInitialization方法,当你通过注册CommonAnnotationBeanPostProcessor或指定<context:annotation-config />in bean配置文件时Spring会意识到它.无论@PostConstruct方法之前或之后任何其他执行postProcessAfterInitialization依赖于order财产

您可以配置多个BeanPostProcessor实例,并且可以通过设置order属性来控制这些BeanPostProcessors的执行顺序.


mar*_*son 25

Bean post处理器的典型示例是当您想要将原始bean包装在代理实例中时,例如在使用@Transactional注释时.

bean后期处理器将被传递给bean的原始实例,它可以调用目标上的任何方法,但它也会返回应该绑定在应用程序上下文中的实际bean实例,这意味着它实际上可以返回任何它想要的对象.这很有用的典型场景是bean后处理器将目标包装在代理实例中.应用程序上下文中绑定的bean上的所有调用都将通过代理,然后代理可以在目标bean的调用之前和/或之后执行一些魔术,例如AOP或事务管理.

  • 感谢现实生活中的榜样! (3认同)

小智 7

不同之处在于BeanPostProcessor将挂钩到上下文初始化然后调用postProcessBeforeInitializationpostProcessAfterInitialization所有定义的bean。

@PostConstruct仅用于特定类,您要在构造函数或 set 方法之后自定义 bean 创建。