ICE09 . playing with java, scala, groovy and spring .

Playing with Spring

Archive for February, 2010

Spring Quicktip: Selecting beans during runtime

Posted by ice09 on February 13, 2010

Sometimes you want to select an actual bean implementation during runtime depending on the availability of other beans.

Example

You have a bean accessor which accesses some external component and is used in several beans all over your application in several application contexts.
Now lets assume you want to change the actual implementation of the accessor bean depending on the availability of some other bean extended-accessor, which might or might not be present during runtime. This selection should be transparent to the existing components, ie. if the bean extended-accessor is not available in the application context, the fallback is using accessor instead.

Implementation

There might be different solutions to this problem, to me the best one is using the magical BeanFactoryPostProcessor.

import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class AccessorBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
	
	protected String extendedTemplate;
	protected String accessorTemplate;
	protected String accessorTemplateFactory;
	
	public void setExtendedTemplate(String extendedTemplate) {
		this.extendedTemplate = extendedTemplate;
	}

	public void setAccessorTemplate(String accessorTemplate) {
		this.accessorTemplate = accessorTemplate;
	}

	public void setAccessorTemplateFactory(String accessorTemplateFactory) {
		this.accessorTemplateFactory = accessorTemplateFactory;
	}
	
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		BeanDefinition beanDefinition = beanFactory.getBeanDefinition(accessorTemplateFactory);
		MutablePropertyValues pvalues = beanDefinition.getPropertyValues();
		Template accessorClass = (Template) (beanFactory.containsBean(extendedTemplate) ? beanFactory.getBean(extendedTemplate) : (Template) beanFactory.getBean(accessorTemplate));   

                //Set the property (the selected bean implementation) now during runtime
		pvalues.addPropertyValue("accessorTemplate", accessorClass);
	}

Now, this bean must be instantiated – it will be passed the bean definition of all beans in the application context. It retrieves the factory bean first, which itself will be dynamically instantiated with the extendedTemplate if it exists and accessorTemplate otherwise.
Together with a factory bean, this looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

        <!-- Here the external definition can be imported (if it is, and the 
               bean extendedTemplate is defined, it will be passed to the factory bean) -->
	<import resource="classpath*:/extension.xml"/>
	
        <!-- Here the actual BeanFactoryPostProcessor is defined, the properties are 
               the Strings which identify the several beans -->
	<bean class="AccessorBeanFactoryPostProcessor">
		<property name="accessorTemplateFactory" value="accessorTemplateFactory"/>
		<property name="extendedTemplate" value="extendedTemplate"/>
		<property name="accessorTemplate" value="accessorTemplate"/>
	</bean>

        <!-- This is the actual bean which is used the the dependent beans - it is created 	
               by the factory bean, which is itself configured by BeanFactoryPostProcessor -->
        <bean id="actualTemplate" factory-bean="accessorTemplateFactory" factory-method="createAccessorTemplate" />

        <!-- This is the actual factory, which itself gets configured by the BeanFactoryPostProcessor -->
	<bean id="accessorTemplateFactory" class="AccessorTemplateFactory">
		<!-- will be modified during runtime -->
	</bean>

	<!-- This is the original accessor template bean, which is selected 
               if the extended bean is not present -->
        <bean id="accessorTemplate" class="AccessorTemplate" />

</beans>

Of course, the beans must implement the same interface. The included extension.xml is quite simple:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

	<bean id="extendedTemplate" class="ExtendedTemplate" />

</beans>

Finally, the factory bean is simple as well, it is used to have a single point of creation – the property accessorBean is set by the BeanFactoryPostProcessor during runtime:

public class AccessorTemplateFactory {

	public Template bean;

	public void setAccessorTemplate(Template arg0) {
		this.bean = arg0;
	}

	public Template createAccessorTemplate() {
		return bean;
	}

}
Advertisements

Posted in BeanFactoryPostProcessor, Spring | 2 Comments »

RESTing with JSON in Gaelyk

Posted by ice09 on February 1, 2010

Note: The complete sourcecode is available on github here (the subproject is ‘gaeloc’). For just downloading, unzipping and importing the project into Eclipse, press on the github site.

Doing REST is getting easier these days, however, there are still substantial differences between ease of usage between different REST frameworks.

A simple, concise approach is illustrated by the new REST support in Spring 3 as described in the previous post about this topic.
However, it can be even simpler. For some Android REST client, I wanted to choose the most intuitive and rapid way to implement a REST server prototype. Once again, I came up with Gaelyk, which I introduced here.

Technologies

  1. Gaelyk, a lightweight Groovy toolkit for the Google App Engine (Java)
  2. Groovy, namely the embeddable groovy-all-jar
  3. Jackson, an intuitive, nice & simple JSON processor
  4. the new Groovy Eclipse plugin

Setup

Currently, the best information about setup, installation and usage of Gaelyk is this post on developerworks.
I just updated the version numbers and changed the injected Google App Engine SDK element names (compare the version history). You will have to do the same if you want to get the downloadable post-project to work with Gaelyk 0.3.2.

The environment is a Eclipse 3.5.1 with the Google Plugin for Eclipse Plugin installed.

  1. Create new Web Application Project
  2. Add the Google App Engine SDK (for this project, GWT is not used)
  3. Add the Gaelyk and Groovy Jars
  4. Add the Jackson dependencies
  5. Add Groovy nature to the project to enable debugging
  6. For debugging, add the WEB-INF/groovy folder to the build path

Configuration

The important parts of the configuration are mentioned in the developerworks post. Just follow the instructions.
Afterwards, the routes for Gaelyk will be enabled and defined:

Changes to web.xml

<filter>
	<filter-name>RoutesFilter</filter-name>
	<filter-class>groovyx.gaelyk.routes.RoutesFilter</filter-class>
</filter>

<filter-mapping>
	<filter-name>RoutesFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

The routes.groovy file in WEB-INF

post "/new-user", forward: "/WEB-INF/groovy/post.groovy"
get "/user/@name", forward: "/WEB-INF/groovy/get.groovy?name=@name"

The post.groovy file called by POST on /new-user

import com.google.appengine.api.datastore.Entity 
import java.text.SimpleDateFormat 
import org.codehaus.jackson.map.ObjectMapper

def requestComplete = new StringBuilder();
while ((line = request.getReader().readLine()) != null) {
	requestComplete.append(line);
}
ObjectMapper mapper = new ObjectMapper(); 
Map map = mapper.readValue(requestComplete.toString(), Map.class);

def user = new Entity("user")
user.name = map.key
user.save()

The get.groovy file called by GET on /user/{ID}

import org.codehaus.jackson.map.ObjectMapper
import com.google.appengine.api.datastore.KeyFactory

if (params["id"]) {
	def id = Long.parseLong(params["id"])
	try {
		def key = KeyFactory.createKey("user", id)
		def user = datastore.get(key)
		ObjectMapper mapper = new ObjectMapper();
		response.contentType = "application/json"
		StringWriter sw = new StringWriter();
		mapper.writeValue(out, user);
	} catch (Throwable t) {
	}
} else {
	forward "index.html"
}

Starting and using the Google App Engine

You can start the Google App Engine locally by choosing “Run As…/Web Application”.

It helps a lot to be able to browse the datastore – this is now possible locally as well by visiting http://localhost:8888/_ah/admin/datastore

Posted in Gaelyk, REST | 2 Comments »