Blog

Using Spring JavaConfig on Google App Engine

17 Jan, 2010
Xebia Background Header Wave

Recently, I put together a Spring demonstration for jclouds, the Java cloud library. This quickly turned into unexpected multi-dimensional experiment in integrating Guice, Google App Engine and Spring, but after much trial-and-error I finally came across a configuration that does the trick – or at least works1 as well as seems possible on GAE.

The tweetstore demo

Tweetstore is a simple web application that demonstrates jclouds’ cloud capabilities. It queries Twitter for mentions of the user’s account and creates a "backup" of this priceless record of your contemporary image in three cloud stores: Amazon S3, Microsoft’s Azure and Rackspace. Nothing less than double redundancy is good enough for your popularity!
The original tweetstore application uses Guice for dependency injection and request mapping. In order to make it as easy as possible to compare the Spring version to the original, I decided to try to similarly do as much in Java code as possible. A perfect opportunity for me to get my hands dirty with Spring 3.0’s support for Java configuration.

Bootstrapping Spring’s Java Configuration

The first, relatively straight-forward step was to convert the Guice servlet module into an equivalent Spring @Configuration:
[java]
@Configuration
public class SpringServletConfig extends LoggingConfig implements ServletConfigAware {
private ServletConfig servletConfig;

@PostConstruct
public void initialize() {

}
@Bean
public StoreTweetsController storeTweetsController() {
StoreTweetsController controller = new StoreTweetsController(providerTypeToBlobStoreMap,
container, twitterClient);
injectServletConfig(controller);
return controller;
}
@Bean
public AddTweetsController addTweetsController() {
AddTweetsController controller = new AddTweetsController(providerTypeToBlobStoreMap,
serviceToStoredTweetStatuses());
injectServletConfig(controller);
return controller;
}
private void injectServletConfig(Servlet servlet) {
try {
servlet.init(checkNotNull(servletConfig));
} catch (ServletException exception) {
throw new BeanCreationException("Unable to instantiate " + servlet, exception);
}
}
@Bean
ServiceToStoredTweetStatuses serviceToStoredTweetStatuses() {
return new ServiceToStoredTweetStatuses(providerTypeToBlobStoreMap, container);
}
@Bean
public HandlerMapping handlerMapping() {
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
Map<String, Object> urlMap = Maps.newHashMapWithExpectedSize(2);
urlMap.put("/store/", storeTweetsController());
urlMap.put("/tweets/
", addTweetsController());
mapping.setUrlMap(urlMap);
/*

Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts