2

I have a class A that implements springs BeanPostProcessor

public class A implements BeanPostProcessor {


   private B b;

   public A() {
      b = new B();
      b.set(...);          
   }


   public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    return bean;
   }

   // Intercept all bean initialisations and return a proxy'd bean equipped with code
   // measurement capabilities
   public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    return b.enhance(bean);
   }


}

I would like to configure my class b which lies inside the my derived BeanPostProcessor class A. How can I configure (dependency inject) this class with spring, is this possible as its inside the BeanPostProcessor...?

MWright
  • 1,681
  • 3
  • 19
  • 31
  • See also http://stackoverflow.com/questions/1201726/tracking-down-cause-of-springs-not-eligible-for-auto-proxying/19688634#19688634 if you get "Bean is not eligible for getting processed by all BeanPostProcessors" – Aaron Digulla Oct 30 '13 at 17:10

2 Answers2

2

With @Configuration classes

public static class Child {}

public static class Processor implements BeanPostProcessor {        
    @Autowired
    public Child child;             
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return null; // Spring would complain if this was executed
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return null; // Spring would complain if this was executed
    }       
}

@Configuration
public static class Config {
    @Bean
    public static Processor processor() {
        return new Processor();
    }
    @Bean
    public Child child() {
        return new Child();
    }
}

public static void main(String[] args) throws IOException, ParseException, JAXBException, URISyntaxException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, SQLException {     
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
    Processor processor = context.getBean(Processor.class);
    System.out.println(processor.child);
}

The BeanPostProcessor doesn't "exist" yet so it can't process the other bean being created (that's required by the @Autowired to finish this bean). The javadoc states

ApplicationContexts can autodetect BeanPostProcessor beans in their bean definitions and apply them to any beans subsequently created.

Bold mine.

With XML

<context:component-scan base-package="test"></context:component-scan>
<bean id="processor" class="test.Main.Processor"></bean>
<bean id="child" class="test.Main.Child"></bean>

ClassPathXmlApplicationContext xmlContext = new ClassPathXmlApplicationContext("context.xml");
processor = xmlContext.getBean(Processor.class);
System.out.println(processor.child);
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
1

You can of course apply dependency injection in your BeanPostProcessor class.

Below is an excerpt from Spring Documentation

Classes that implement the BeanPostProcessor interface are special, and so they are treated differently by the container. All BeanPostProcessors and their directly referenced beans will be instantiated on startup, as part of the special startup phase of the ApplicationContext, then all those BeanPostProcessors will be registered in a sorted fashion - and applied to all further beans.

Debojit Saikia
  • 10,532
  • 3
  • 35
  • 46