Deca
Deca

Reputation: 1235

How to avoid BeanPostProcessor from executing after every beans and its usage in real use case

I have gone through Spring's documentation for BeanPostProcessor and existing stackoverflow posts with respect to it. And I can understand that BeanPostProcessor has two methods postProcessAfterInitialization and postProcessBeforeInitialization. While postProcessBeforeInitialization gets invoked after Spring Bean is initialised and before init() method is called and postProcessAfterInitialization is invoked just after init(). However I have couple of questions regarding its behaviour.

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

I have written 2 POJO classes, 1 main class, 1 custom BeanPostProcessor class and 1 spring bean xml file.

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);
   }
}

MAIN Class

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");
   }
}

Custom 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;
    }
}

Beans Xml File

<?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:- Irrespective of the init and destroy methods I write in my POJOs, BeanPostProcessor is executed after both the bean instantiation. In that case, how does the definition hold true where it states that it will be executed before and after init method as I don't have init for one of the POJOs, but still it gets executed.

Question#2:- Inside the methods of BeanPostProcessor, we have logic such as connecting to a remote db, executing some jms queue, etc. We would not want executing these logics after every bean. In that case we should have some mechanism where BeanPostProcessor is not run after bean. How can that be achieved. If its not achievable, then what kind of operations we usually write inside BeanPostProcessor methods in real world use case?

Upvotes: 0

Views: 1136

Answers (1)

Yevhen Surovskyi
Yevhen Surovskyi

Reputation: 961

The main idea of BeanPostProcessor is to configure your beans. The common use case is to wrap beans that annotated particular annotation with proxy. If you have some logic like executing jms queue may be it will be better to create separate bean and in @PostConstruct method do this logic.

Upvotes: 0

Related Questions