Spring Corner - What are those Post Processor Beans Anyway?
Join the DZone community and get the full member experience.
Join For FreeHey there, Spring Fans! Ever look into your Spring configuration files and see beans that end in the name PostProcessor? What does that mean? And more importantly, why should I care?
The Spring Container Lifecycle
When you mount an application context, Spring starts up, following a predictable lifecycle. The actions it performs are:
- Load all bean definitions before constructing beans
- Construct each bean via reflection
- Inject components via setters, autowired methods, etc...
- Post-process the bean
- Make the bean available for use by injection or direct lookup
Bean Post Processors
There are a number of pre-defined post processor beans. For example, the RequiredAnnotationPostProcessor looks for any beans annotated with the @Required annotation, and if the property isn't set during startup, the post processor will throw an exception and stop the startup of the container. From the definition:
for (PropertyDescriptor pd : pds) {
if (isRequiredProperty(pd) && !pvs.contains(pd.getName())) {
invalidProperties.add(pd.getName());
}
}
if (!invalidProperties.isEmpty()) {
throw new BeanInitializationException(
buildExceptionMessage(invalidProperties, beanName));
}
Why are BeanPostProcessors important?
Spring uses BeanPostProcessors everywhere to enable features such as security, transaction processing, remoting, JMX monitoring, and a number of other features. Besides mounting a bean directly, you install these post-processors when you use certain Spring namespace features. For example:
<tx:annotation-driven>
This statement mounts a bean post processor that watches your beans for the @Transactional annotation, and wraps the beans in a proxy class that watches calls to methods, and coordinates with the Spring transaction manager.
Post-processing your own code
You can write your own bean post processor to inspect a newly-created bean, and potentially modify it or return another bean entirely. There are a number of ways to do this, starting with implementing BeanPostProcessor.
Startup Methods
A simpler way to initiate an on-startup process that is Spring 3.0 and annotation friendly is to mount a bean post processor known as the CommonAnnotationPostProcessor bean and use the @PostConstruct Java EE annotation on a method in your class. For example:
@Component
public class MyServiceBean implements MyService {
@PostConstruct
public void initialize() {
// do something here
}
...
}
How to find out more...
Open up your favorite IDE (SpringSource Tool Suite is great for this) and lookup the source for BeanPostProcessor. Ask the IDE to show you all implementing classes - of which there are a lot. Here is another example - the BeanValidationPostProcessor which implements JSR-303 Java EE Bean Validation on methods annotated with @Valid:
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if (this.afterInitialization) {
doValidate(bean);
}
return bean;
}
...
protected void doValidate(Object bean) {
Set<ConstraintViolation<Object%gt;%gt; result = this.validator.validate(bean);
if (!result.isEmpty()) {
StringBuilder sb = new StringBuilder("Bean state is invalid: ");
for (Iterator%lt;ConstraintViolation%lt;Object%gt;%gt;
it = result.iterator(); it.hasNext();) {
ConstraintViolation<Object> violation = it.next();
sb.append(violation.getPropertyPath()).append(" - ")
.append(violation.getMessage());
if (it.hasNext()) {
sb.append("; ");
}
}
throw new BeanInitializationException(sb.toString());
}
}
Because Spring is open source, you can easily read and even debug source
code in the framework. Use this to your advantage, and really dig in
and learn how it operates. If you use Spring Roo, you can even have an
entire application platform built for you, including source-code pathing
from Maven repositories, so you can just look up the classes and see
the source code.
From http://www.rimple.com/tech/2011/2/21/spring-corner-what-are-those-post-processor-beans-anyway.html
Opinions expressed by DZone contributors are their own.
Comments