Login | Register   
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Bridging Configuration from Spring to Legacy Frameworks

Spring's POJO-based programming model has proven to be a much better way to write, test, and assemble robust Java EE applications, but it works only if you configure your objects with Spring. What happens when you combine Spring with an in-house legacy framework or Java EE technology such as EJBs or servlets?


advertisement
he Spring framework and its Plain Old Java Object (POJO)-based programming model enable you to inject collaborative objects into your classes via setter methods instead of looking them up inline via factory or locator classes. This approach is not only more intuitive, but it also drastically reduces the amount of code you need to write. In fact, Spring's POJO-based programming model has proven to be a much better way to write, test, and assemble robust Java EE applications. But it works only if you configure your objects with Spring.

What happens when you combine Spring with an in-house legacy framework or Java EE technology such as EJBs or servlets? Suppose you have some objects defined outside of Spring (via your legacy services configuration), while others are defined and managed inside the Spring container. Can you extend Spring's configuration to simplify and standardize your legacy framework? Maybe the biggest problem you face in trying to do so is that Spring and your legacy framework have competing bootstrapping processes. The Spring IOC container has a start-up process defined by the creation of a BeanFactory, and your legacy framework has its own rules for starting up servers.

The lazy solution would be to load Spring the first time a legacy service needs to refer to a bean. As an example of this approach, the following listing shows a typical combination of a legacy framework with Spring:



public class MyLegacyService extends SomePreIOC_AbstractService { Pojo1 pojo1; Pojo2 pojo2; public void setPojo1(Pojo1 p1) { pojo1 = p1; } public void setPojo2(Pojo2 p2) { pojo2 = p2; } public MyLegacyService(String serviceName) { super(serviceName); } // some pre-dependency injection configure method // called by the legacy framework. public void configure(ServiceConfig config) { super.configure(config); setPojo1((Pojo1) SpringSingleton. getBeanFactory(). getBean("pojo.1")); setPojo2((Pojo2) SpringSingleton. getBeanFactory(). getBean("pojo.2")); } }

The service MyLegacyService is created outside of Spring but needs to refer to Spring managed beans. Notice the explicit calls to access the specific Spring beans pojo.1 and pojo.2.

The following is the corresponding Spring configuration:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="pojo.1" class="Pojo1" /> <bean id="pojo.2" class="Pojo2" /> </beans>

One subtle problem with this approach is that it is not clear how Spring managed objects can refer to your legacy service. Typically in Spring, you access objects created outside of the IOC container with a FactoryBean. This works extremely well for objects in a JNDI context, because the JNDI context typically will exist and be available prior to Spring starting. In the case of a legacy framework, however, you may not be able to guarantee that a FactoryBean will obtain an instance to an initialized legacy service. As an example, imagine the bean pojo.1 also needs a reference to its associated instance of MyLegacyService.

An ideal solution would be a configuration mechanism that supports your cyclical dependencies (MyLegacyService depending on Pojo1, and Pojo1 depending on MyLegacyService), yet remains flexible so that it doesn't matter which bootstrapping process starts first. In other words, you wouldn't need to care whether the external service is created first or it is referenced in Spring first.

The Oranjestad Spring project defines just such an extension to Spring. It allows you to register your legacy objects so that they can be configured via Spring. It does this using Spring's namespaces extension point (see Sidebar 1. How Do External Beans Work?).

To use Oranjestad Spring, you first include an external namespace, which requires you to remove the standard DTD reference and import the external namespace in the beans tag:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:external="http://oranjestad.sourceforge.net/schema/external" xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://oranjestad.sourceforge.net/schema/external
http://oranjestad.sourceforge.net/schema/external/external_1.0.xsd">

Then you add a Spring-style bean definition to define your configuration. The definition will be applied to your external legacy service:

<external:bean id="some.service" class="MyLegacyService"> <constructor-arg type="java.lang.String"><value>…</value></constructor-arg> <property name="pojo1" ref="pojo.1" /> <property name="pojo2" ref="pojo.2" /> </external:bean>

Other than the external namespace qualifier, the revised XML configuration looks and acts exactly like a standard Spring definition and allows you to define your circular reference between the external legacy service (referred to as some.service in the Spring file) and pojo.1:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:external="http://oranjestad.sourceforge.net/schema/external" xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://oranjestad.sourceforge.net/schema/external
http://oranjestad.sourceforge.net/schema/external/external_1.0.xsd"> <external:bean
id="some.service" class="MyLegacyService"> <constructor-arg type="java.lang.String"><value>…</value></constructor-arg> <property name="pojo1" ref="pojo.1" /> <property name="pojo2" ref="pojo.2" /> </external:bean> <bean id="pojo.1" class="Pojo1"> <property name="someService" ref="some.service" /> </bean> <bean id="pojo.2" class="Pojo2" /> </beans>



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap