Ken Rimple heads Chariot Solutions' training and mentoring programs, and has developed and/or delivered courseware and seminars in a variety of technologies such as Maven, OSGi, Groovy, Grails and Spring. Throughout his career, Ken has always made it a priority to teach others what he has learned. Ken has served as the technical co-chair of both the Fall Forecast 2008 Cloud Computing Conference and the 2009 - 2012 Emerging Technologies for the Enterprise conferences. He hosts a popular podcast, the Chariot TechCast, and has led or participated in projects written in Java since Java 1.0.2. Ken taught the first Philadelphia-area Sun Introduction to Java course in the late 1990s. He is the co-author (along with Srini Penchikala) of Spring Roo in Action for Manning Publications. He is also an avid photographer and jazz drummer. Ken is a DZone MVB and is not an employee of DZone and has posted 35 posts at DZone. You can read more from them at their website. View Full User Profile

Spring Corner - What are those Post Processor Beans Anyway?

02.22.2011
| 7574 views |
  • submit to reddit

Hey 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:

  1. Load all bean definitions before constructing beans
  2. Construct each bean via reflection
  3. Inject components via setters, autowired methods, etc...
  4. Post-process the bean
  5. Make the bean available for use by injection or direct lookup
Obviously we're going to focus on that post-processing step. It turns out Post Processing allows Spring's magic to happen.

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

Published at DZone with permission of Ken Rimple, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags: