Use Spring’s BeanPostProcessor to wrap beans
What I learned today — 18 April 2018
1 min readApr 18, 2018
Spring’s BeanPostProcessor provides a simple way to modify beans after creation. One way of doing that is by wrapping a bean with another object implementing the same interface. Suppose you have beans of type Function
(contrived, I know, but this is about as simple as it gets):
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.function.Function;
@Configuration
public class FunctionWrapperConfiguration {
private static Logger LOGGER = LoggerFactory.getLogger(FunctionWrapper.class);
@Bean
public BeanPostProcessor entityManagerBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof Function) {
return new FunctionWrapper((Function) bean);
}
return bean;
}
};
}
private class FunctionWrapper<T, R> implements Function<T, R> {
private Function<T, R> delegate;
public FunctionWrapper(Function<T, R> delegate) {
this.delegate = delegate;
}
@Override
public R apply(T t) {
LOGGER.debug("Function applied with value {}", t);
return delegate.apply(t);
}
}
}
In this snippet I show how to use a Java configuration of a BeanPostProcessor to wrap an object.
BeanPostProcessors are powerful tools and can easily be abused. Don’t use them to patch poor configuration in other parts of your system.