首页 > 解决方案 > 如何避免 BeanPostProcessor 在每个 bean 之后执行及其在实际用例中的使用

问题描述

我已经阅读了 Spring 的 BeanPostProcessor 文档和现有的关于它的 stackoverflow 帖子。而且我可以理解 BeanPostProcessor 有两个方法postProcessAfterInitializationpostProcessBeforeInitialization. 而 postProcessBeforeInitialization 在 Spring Bean 初始化之后和 init() 方法被调用之前被调用,而 postProcessAfterInitialization 在 init() 之后被调用。但是我有几个关于它的行为的问题。

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/config/BeanPostProcessor.html

我编写了 2 个 POJO 类、1 个主类、1 个自定义 BeanPostProcessor 类和 1 个 spring bean xml 文件。

public class HelloWorld{
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }
   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
   
   public void init() {
        System.out.println("I am init");
   }
    
   public void destroy() {
        System.out.println("I am destroy");
   }
}

POJO

public class NewHelloWorld{
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }
   public void getMessage(){
      System.out.println("NewHelloWorld Your Message : " + message);
   }
}

主要课程

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      ((AbstractApplicationContext)context).registerShutdownHook();
      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      NewHelloWorld newObj = (NewHelloWorld) context.getBean("newHelloWorld");
   }
}

自定义 BeanPostProcessor

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class DemoBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessAfterInitialization(Object arg0, String arg1) throws BeansException {
        System.out.println(arg1 + ": I am executing immediately after init method");
        return arg0;
    }
    
    @Override
    public Object postProcessBeforeInitialization(Object arg0, String arg1) throws BeansException{
        System.out.println(arg1 + ": I am executing after spring bean initialization but before init method");
        return arg0;
    }
}

豆类 XML 文件

<?xml version="1.0" encoding="UTF-8"?>  
<beans  
    xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:util="http://www.springframework.org/schema/util" 
    xmlns:p="http://www.springframework.org/schema/p"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
  
<bean id="helloWorld" class="com.HelloWorld" init-method="init" destroy-method="destroy">
    <property name="message" value="helloworld-bean" />
</bean>

<bean id="newHelloWorld" class="com.NewHelloWorld">
    <property name="message" value="NewHelloworld-bean" />
</bean>

<bean class="com.tutorialspoint.DemoBeanPostProcessor" />

</beans>

Question#1:- 无论我在 POJO 中编写的 init 和 destroy 方法如何,BeanPostProcessor 都会在 bean 实例化之后执行。在这种情况下,定义如何在它声明它将在 init 方法之前和之后执行的情况下成立,因为我没有针对其中一个 POJO 的 init,但它仍然被执行。

Question#2:- 在 BeanPostProcessor 的方法中,我们有诸如连接到远程数据库、执行一些 jms 队列等逻辑。我们不希望在每个 bean 之后执行这些逻辑。在那种情况下,我们应该有一些机制,使 BeanPostProcessor 不在 bean 之后运行。怎么可能达到。如果它无法实现,那么在现实世界的用例中,我们通常在 BeanPostProcessor 方法中编写什么样的操作?

标签: javaspringspring-boot

解决方案


BeanPostProcessor 的主要思想是配置你的 bean。常见的用例是用代理包装注释特定注释的bean。如果您有一些逻辑,例如执行 jms 队列,那么创建单独的 bean 并在 @PostConstruct 方法中执行此逻辑会更好。


推荐阅读