Bridging Configuration from Spring to Legacy Frameworks

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:

     "http://www.springframework.org/dtd/spring-beans.dtd">          

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:

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

 id="some.service" class="MyLegacyService">                ref="some.service" /> 

The only other detail to cover is how your legacy service registers itself so that the Spring configuration can be applied to it. You accomplish this by using the oranjestad class SpringConfigurationBridge, which is called by the service after it has been initialized:

import oranjestad.spring.bootstrap.SpringConfigurationBridge;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);	   SpringConfigurationBridge.            configure(this, "some.service");    }}

With the external bean approach, you have much greater flexibility with services that get created in an intertwined fashion. External beans do the following for your legacy system:

  • Handle all combinations of the legacy services starting before or after Spring
  • Extend dependency injection to your legacy system
  • Add some automatic annotation-based capabilities such as Spring’s JMX annotations for creating MBeans to work with your legacy service

This approach can greatly increase the adoption of Spring into a legacy framework by eliminating ugly bean lookups from the legacy service as well as by moving configuration from the legacy system to Spring.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

The Latest

your company's audio

4 Areas of Your Company Where Your Audio Really Matters

Your company probably relies on audio more than you realize. Whether you’re creating a spoken text message to a colleague or giving a speech, you want your audio to shine. Otherwise, you could cause avoidable friction points and potentially hurt your brand reputation. For example, let’s say you create a

chrome os developer mode

How to Turn on Chrome OS Developer Mode

Google’s Chrome OS is a popular operating system that is widely used on Chromebooks and other devices. While it is designed to be simple and user-friendly, there are times when users may want to access additional features and functionality. One way to do this is by turning on Chrome OS

homes in the real estate industry

Exploring the Latest Tech Trends Impacting the Real Estate Industry

The real estate industry is changing thanks to the newest technological advancements. These new developments — from blockchain and AI to virtual reality and 3D printing — are poised to change how we buy and sell homes. Real estate brokers, buyers, sellers, wholesale real estate professionals, fix and flippers, and beyond may