5

I have a parent bean factory and I'd like a BeanPostProcessor in it to post process beans in child factories. AFAIK, this isn't supported in Spring. What are my alternatives? (except of course to declare the post processor in the XML of each child factory)

animuson
  • 53,861
  • 28
  • 137
  • 147
IttayD
  • 28,271
  • 28
  • 124
  • 178
  • There are no other alternatives that I'm aware of, other than making more sparing use of parent-child contexts. – skaffman Dec 12 '10 at 08:57

1 Answers1

0

One "solution" is to add a bean post processor to the child context that executes the parent post processors. This is the technique we ended up using. It is potentially dangerous and not the best Spring practice IMO.

/**
 * A {@linkplain BeanPostProcessor} that references the BeanPostProcessors in the parent context and applies them
 * to context this post processor is a part of. Any BeanPostProcessors from the parent that are {@link BeanFactoryAware} will
 * have the {@linkplain BeanFactory} from the child context set on them during the post processing. This is necessary to let such post processors
 * have access to the entire context.
 */
public class ParentContextBeanPostProcessor implements BeanPostProcessor {

  private final Collection<BeanPostProcessor> parentProcessors;
  private final BeanFactory beanFactory;
  private final BeanFactory parentBeanFactory;

  /**
   * @param parent the parent context
   * @param beanFactory the beanFactory associated with this post processor's context
   */
  public ParentContextBeanPostProcessor(ConfigurableApplicationContext parent, BeanFactory beanFactory) {
    this.parentProcessors = parent.getBeansOfType(BeanPostProcessor.class).values();
    this.beanFactory = beanFactory;
    this.parentBeanFactory = parent.getBeanFactory();
  }

  /** {@inheritDoc} */
  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    for (BeanPostProcessor processor : parentProcessors) {
      if (processor instanceof BeanFactoryAware) {
        ((BeanFactoryAware) processor).setBeanFactory(beanFactory);
      }
      try {
        bean = processor.postProcessBeforeInitialization(bean, beanName);
      } finally {
        if (processor instanceof BeanFactoryAware) {
          ((BeanFactoryAware) processor).setBeanFactory(parentBeanFactory);
        }
      }
    }
    return bean;
  }

  /** {@inheritDoc} */
  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    for (BeanPostProcessor processor : parentProcessors) {
      if (processor instanceof BeanFactoryAware) {
        ((BeanFactoryAware) processor).setBeanFactory(beanFactory);
      }
      try {
        bean = processor.postProcessAfterInitialization(bean, beanName);
      } finally {
        if (processor instanceof BeanFactoryAware) {
          ((BeanFactoryAware) processor).setBeanFactory(parentBeanFactory);
        }
      }
    }
    return bean;
  }
}
Martin Serrano
  • 3,727
  • 1
  • 35
  • 48