Spring-Enhanced Abstract BeansThe Spring framework provides a mechanism for replacing abstract bean methods with bean instances defined in the Spring configuration context. This functionality is provided by the 'lookup-method' element in the Spring context. In this article we present a utility that combines the functionality of the 'lookup-method' element with the convenience of Spring by-name autowiring. Implementing bean attributes for use in Java-bean aware environment such a Spring context consists of 2 steps:
As trivial as it is, this task becomes tedious for several beans and attributes. The approach employed in the Tapestry web framework is much easier: <bean id="service" class="service"/> <bean id="user" class="User"> <lookup-method name="getService" bean="service"/> </bean> calls to the bean "user" abstract method getService() will return the "service" bean instance. Although very close to the desired behaviour, the approach can be further enhanced with the convenience of Spring's autowiring by-name. In this case the mapping of bean instance to method name is not needed. The bean is defined in the Spring context as any other concrete bean implementation. Then for every abstract method get{Attribute}, a bean instance with ID "Attribute" is looked up in the Spring context. Similarly a call to set{Attribute} will assign the bean with ID "Attribute" to the bean's "Attribute" property. Spring does not provide such a utility, but implementing this is not very hard. This is the purpose of the BeanContextFactory bean factory. It enhances a bean's implementation by replacing abstract bean get/set methods with concrete implementations using CGLIB. It will then perform autowiring by-name on the bean and return the configured bean instance. E.g. for context ctx.xml: <bean id="bean" class="Bean"> and an abstract bean:<property name="value" value="result"/> </bean> public static abstract class Example { public abstract Bean getBean(); public String call() { return getBean().getValue(); } } Example use: Example proxy = (Example)BeanContextFactory.get(Example.class, new ClassPathXmlApplicationContext("ctx.xml")); proxy.call(); The last call returns the string "result". |
|