Spring 中的 BeanPostProcessor 和 init/destroy 方法有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9862127/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 05:01:39  来源:igfitidea点击:

What is the difference between BeanPostProcessor and init/destroy method in Spring?

spring

提问by LuckyLuke

What is the difference between implementing the BeanPostProcessorinterface and either using the init/destroymethod attributes in the XML configuration file in Spring or implementing InitializingBean/DisposableBeaninterface?

实现BeanPostProcessor接口和在 Spring 中使用 XML 配置文件中的init/destroy方法属性或实现InitializingBean/DisposableBean接口有什么区别?

回答by Emil H

This is pretty clearly explained in the Spring documentation about the Container Extension Points.

这在关于容器扩展点的 Spring 文档中有非常清楚的解释。

The BeanPostProcessor interface defines callback methods that you can implement to provide your own (or override the container's default) instantiation logic, dependency-resolution logic, and so forth. If you want to implement some custom logic after the Spring container finishes instantiating, configuring, and initializing a bean, you can plug in one or more BeanPostProcessor implementations.

BeanPostProcessor 接口定义了回调方法,您可以实现这些方法来提供您自己的(或覆盖容器的默认)实例化逻辑、依赖项解析逻辑等。如果要在 Spring 容器完成对 bean 的实例化、配置和初始化之后实现一些自定义逻辑,可以插入一个或多个 BeanPostProcessor 实现。

So in essence the method postProcessBeforeInitializationdefined in the BeanPostProcessor gets called (as the name indicates) before the initialization of beans and likewise the postProcessAfterInitializationgets called after the initialization of the bean.

因此,本质上postProcessBeforeInitializationBeanPostProcessor 中定义的方法在 bean 初始化之前被调用(如名称所示),同样postProcessAfterInitialization在 bean 初始化之后被调用。

The difference to the @PostConstruct, InitializingBeanand custom initmethod is that these are defined on the bean itself. Their ordering can be found in the Combining lifecycle mechanismssection of the spring documentation.

@PostConstruct,InitializingBean和 custominit方法的区别在于,它们是在 bean 本身上定义的。它们的顺序可以在 spring 文档的组合生命周期机制部分找到。

So basically the BeanPostProcessor can be used to do custom instantiation logic for several beans wheras the others are defined on a per bean basis.

所以基本上 BeanPostProcessor 可用于为多个 bean 执行自定义实例化逻辑,而其他 bean 是基于每个 bean 定义的。

回答by neo

Above answers clearly explains some of the very important aspect.

以上答案清楚地解释了一些非常重要的方面。

Apart from that it's also important to understand that both beanPostProcessor and init and destroy methods are part of the Spring bean life cycle.

除此之外,理解 beanPostProcessor 和 init 和 destroy 方法都是 Spring bean 生命周期的一部分也很重要。

BeanPostProcessor class has two methods.

BeanPostProcessor 类有两个方法。

1) postProcessBeforeInitialization - as name clearly says that it's used to make sure required actions are taken before initialization. e.g. you want to load certain property file/read data from the remote source/service.

1) postProcessBeforeInitialization - 顾名思义,它用于确保在初始化之前执行所需的操作。例如,您想从远程源/服务加载某些属性文件/读取数据。

2) postProcessAfterInitialization - any thing that you want to do after initialization before bean reference is given to application.

2) postProcessAfterInitialization - 在将 bean 引用提供给应用程序之前,您在初始化之后想要做的任何事情。

Sequence of the questioned methods in life cycle as follows :

生命周期中被质疑方法的顺序如下:

1) BeanPostProcessor.postProcessBeforeInitialization()

1) BeanPostProcessor.postProcessBeforeInitialization()

2) init()

2) 初始化()

3) BeanPostProcessor.postProcessAfterInitialization()

3) BeanPostProcessor.postProcessAfterInitialization()

4) destroy()

4) 销毁()

You may check this by writing simple example having sysout and check their sequence.

您可以通过编写具有 sysout 的简单示例并检查它们的顺序来检查这一点。

回答by vjay

And one more main diff is InitializingBean,DisposableBean related afterPropertiesSet() & destory() methods did not accept any paratmeters and return type also void, so we did not implement any custom logic. But coming to BeanPostProcess methods postProcessBeforeInitialization(Object bean,String beanName) and postProcessAfterInitilization(Object bean,String beanName) are accept those two paramaters and return type also Object so we are able to write initilzation logics as well as any custom login based on the passing bean...

还有一个主要区别是 InitializingBean、DisposableBean 相关 afterPropertiesSet() 和 destory() 方法不接受任何参数并且返回类型也是无效的,因此我们没有实现任何自定义逻辑。但是来到 BeanPostProcess 方法 postProcessBeforeInitialization(Object bean,String beanName) 和 postProcessAfterInitilization(Object bean,String beanName) 接受这两个参数并且返回类型也是 Object 所以我们能够编写初始化逻辑以及任何基于传递的自定义登录豆角,扁豆...

These both callback method feautes are including the bean life cycle and the following are the life cycle as follows

这两个回调方法特征都包括bean生命周期,以下是生命周期如下

1) BeanPostProcessor.postProcessBeforeInitilazation()

1) BeanPostProcessor.postProcessBeforeInitilazation()

2) @postConstruct or InitializingBean.afterPropertiesSet() or initialization method which is
defining in xml /*here also it's following the same oredr if three ways are availiable **/

2) @postConstruct 或 InitializingBean.afterPropertiesSet() 或
在 xml 中定义的初始化方法/ *这里也遵循相同的 oredr 如果三种方式可用 **/

3) BeanPostProcessor.postProcessAfterInitialization()

3) BeanPostProcessor.postProcessAfterInitialization()

4) @preDestroy or DisposibleBean.destroy() or destroy method which is defining in xml /*here also it's following the same oredr if three ways are availiable **/

4) @preDestroy 或 DisposibleBean.destroy() 或在 xml 中定义的 destroy 方法 / *这里也遵循相同的 oredr 如果三种方式可用 **/

回答by Premraj

Init and Destroy callback methodsare part of Spring bean life cycle phases. The initmethod is going to be executed after bean instantiation. Similarly, The destroymethod is going to be executed before bean finalization.

Init 和 Destroy 回调方法是 Spring bean 生命周期阶段的一部分。该初始化方法去豆实例化后执行。同样,destroy方法将在 bean 终结之前执行。

We can implement this functionality using implementing interfaces InitializingBeanand DisposableBean, or using annotations @postconstructand @predestroy, or declare the <bean>with init-methodand destroy-methodattributes.

我们可以使用实现接口InitializingBeanand来实现这个功能DisposableBean,或者使用注解@postconstructand @predestroy,或者声明<bean>withinit-methoddestroy-method属性。

BeanPostProcessor interfaceis used for extending the functionality of framework if want to do any configuration Pre- and Post- bean initialization done by spring container.

BeanPostProcessor 接口用于扩展框架的功能,如果要进行任何配置,则 Spring 容器完成的 Pre- 和 Post-bean 初始化。

For Example: By default, Spring will not aware of the @PostConstructand @PreDestroyannotation. To enable it, we have to either register CommonAnnotationBeanPostProcessoror specify the <context:annotation-config />in bean configuration file. Here CommonAnnotationBeanPostProcessoris predefined BeanPostProcessorimplementation for the annotations. Like:

例如:默认情况下,Spring 不会意识到@PostConstructand@PreDestroy注释。要启用它,我们必须注册CommonAnnotationBeanPostProcessor或指定<context:annotation-config />in bean 配置文件。这CommonAnnotationBeanPostProcessorBeanPostProcessor注释的预定义实现。喜欢:

@Requiredenables RequiredAnnotationBeanPostProcessorprocessing tool
@Autowiredenables AutowiredAnnotationBeanPostProcessorprocessing tool

@Required启用 RequiredAnnotationBeanPostProcessor处理工具
@Autowired启用 AutowiredAnnotationBeanPostProcessor处理工具

回答by IqbalHamid

Just a short supplement to all the answers above: If you have any generic logic, common logic that needs to be universally applied to all your Spring beans, such as the injection of a logger to your beans, setting of a properties file, setting default values to fields of your beans through reflection; you could put that logic into ONE single place: the @Overriden callbacks (eg: postProcessBeforeInitialization(Object arg0, String arg1)if you are implementing the BeanPostProcessorinterface); instead of duplicating the same logic across all your beans.

只是对上述所有答案的简短补充:如果您有任何通用逻辑,需要普遍应用于所有 Spring bean 的通用逻辑,例如向 bean 注入记录器、设置属性文件、设置默认值通过反射对 bean 的字段进行赋值;您可以将该逻辑放在一个地方:@Overriden 个回调(例如:postProcessBeforeInitialization(Object arg0, String arg1)如果您正在实现BeanPostProcessor接口);而不是在所有 bean 中复制相同的逻辑。

回答by Sandhya Bhat

a)The postProcessBeforeInitialization() will be called before initialization of the bean.

a) postProcessBeforeInitialization() 将在 bean 初始化之前被调用。

b)Once the bean gets initialized, the different callbacks methods are called in the following order as per the Spring docs:

b) 一旦 bean 被初始化,不同的回调方法将按照 Spring 文档按以下顺序调用:

  1. Methods annotated with @PostConstruct
  2. afterPropertiesSet() as defined by the InitializingBean callback interface
  3. init method defined through the XML.
  1. 用@PostConstruct 注释的方法
  2. afterPropertiesSet() 由 InitializingBean 回调接口定义
  3. init 方法通过 XML 定义。

The main difference is that the above 3 methods get called after the initialization get completed by the postProcessBeforeInitialization() method.

主要区别在于,上述 3 个方法是在 postProcessBeforeInitialization() 方法完成初始化后调用的。

Once these methods get completed the method postProcessAfterInitialization() will be called and then the destroy methods are called in the same order:

一旦这些方法完成,将调用 postProcessAfterInitialization() 方法,然后以相同的顺序调用 destroy 方法:

  1. Methods annotated with @PreDestroy

  2. destroy() as defined by the DisposableBean callback interface

  3. destroy() method defined through the XML.

  1. 用@PreDestroy 注释的方法

  2. destroy() 由 DisposableBean 回调接口定义

  3. destroy() 方法通过 XML 定义。