Spring bean后期处理器的工作原理
我正在学习Spring Coreauthentication,我对Spring如何处理bean的生命周期 ,特别是bean后置处理器有一些疑问。
所以我有这个模式:
这对我来说很清楚这意味着什么:
进入负载Bean定义阶段发生:
-
对@Configuration类进行处理和/或对@Component进行扫描和/或对XML文件进行parsing。
-
添加到BeanFactory的Bean定义(每个定义在它的id下)
-
调用特殊的BeanFactoryPostProcessor bean,它可以修改任何bean的定义(例如对于属性占位符值的replace)。
然后在bean创build阶段发生:
-
每个bean都是默认实例化的(创build的顺序依赖于注入的依赖关系)。
-
在dependency injection之后,每个bean都经历一个后期处理阶段,在这个阶段中可能会进行进一步的configuration和初始化。
-
在后处理后,bean被完全初始化并准备好使用(通过它的id跟踪,直到上下文被销毁)
好的,这对我来说很清楚,我也知道有两种types的bean后期处理器 :
-
初始化程序:如果指示了初始化bean(即@PostConstruct)。
-
剩下的部分:允许额外的configuration,并可能在初始化步骤之前或之后运行
我张贴这张幻灯片:
因此,我很清楚初始化 bean的后处理器(它们是用@PostContruct注解来注释的方法,并且在setter方法之后立即被自动调用(所以在注入dependency injection之后),并且我知道我可以使用执行一些初始化批处理(如前一个例子中的填充caching)。
但是,究竟代表另一个豆后期处理器呢? 这意味着什么是在初始化阶段之前或之后执行的?
所以我的bean被实例化,并执行dependency injection,然后初始化阶段被执行(通过执行@PostContruct注释的方法)。 什么意思是在初始化阶段之前执行Bean Post Processor? 这意味着它发生在@PostContruct注释的方法执行之前? 所以int意味着它可能发生在dependency injection之前(在调用setter方法之前)?
究竟是什么意思,它是在初始化步骤后执行的 。 这意味着它发生在@PostContruct注释方法的执行之后,还是什么?
我可以很容易地想到我的头为什么我需要一个@PostContruct注释的方法,但我不能想出另一种豆后处理器的典型例子,你能告诉我什么时候使用的典型例子吗?
TNX
Spring doc解释了使用BeanPostProcessor定制bean的BPP。 BPP bean是一种特殊的bean,在任何其他bean之前创build并与新创build的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; } }
将被调用并为每个创build的bean打印出类和bean的名字。
为了说明这个方法如何符合bean的生命周期,以及何时调用方法的get方法来检查文档
postProcessBeforeInitialization(Object bean,String beanName)在任何Bean初始化callback(如InitializingBean的afterPropertiesSet或自定义init方法)之前,将此BeanPostProcessor应用于给定的新bean实例。
postProcessAfterInitialization(Object bean,String beanName)在任何bean初始化callback(如InitializingBean的afterPropertiesSet或自定义init方法)之后,将此BeanPostProcessor应用于给定的新bean实例。
重要的一点也是
这个bean已经被填充了属性值。
关于与@PostConstruct
的关系请注意,这个注释是一个声明postProcessAfterInitialization
方法的简便方法,当你通过注册CommonAnnotationBeanPostProcessor
或者在beanconfiguration文件中指定<context:annotation-config />
时,Spring就会意识到它。 在任何其他postProcessAfterInitialization
之前或之后执行@PostConstruct
方法取决于order
属性
您可以configuration多个BeanPostProcessor实例,您可以通过设置顺序属性来控制这些BeanPostProcessor执行的顺序。
一个bean后期处理器的典型例子就是当你想将原始的bean包装在一个代理实例中时,例如当使用@Transactional
注解时。
bean后置处理器将交给bean的原始实例,它可以调用目标上的任何方法,但它也返回应该在应用上下文中绑定的实际bean实例,这意味着它实际上可以返回任何它想要的对象。 当这种情况很有用的时候,典型的场景是bean后置处理器将目标包装在代理实例中。 所有对绑定在应用上下文中的bean的调用都将通过代理,然后代理会在调用目标bean之前和/或之后执行一些魔术,例如AOP或事务pipe理。