To compare and contrast the different development approaches between J2EE and Spring, we took the MedRec sample application and rewrote it using the Spring Framework. In the next section, we give a brief overview of MedRec's general architecture and then look at it in its J2EE form followed by its Spring form.
Avitek Medical Records (or MedRec) is a WebLogic Server sample application suite that concisely demonstrates all aspects of the J2EE platform. MedRec is designed as an educational tool for all levels of J2EE developers. It showcases the use of each J2EE component and illustrates design patterns for component interaction and client development. MedRec also illustrates best practices for developing and deploying applications with WebLogic Server.
The real-world concept behind MedRec is a framework for patients, doctors, and administrators to manage patient data using a variety of different clients. For patients, MedRec provides a Web-based application for users to view their medical record history and maintain a profile. For administrators, MedRec provides a Web-based application to manage incoming registrations, medical record uploads, and general application monitoring. MedRec also has resources for interfacing with independent medical institutions. To demonstrate this communication, MedRec consists of a physician application to request and provide data to MedRec’s system.
The J2EE and WebLogic Server version of MedRec is designed and implemented following the traditional three-tier architecture model in which the client, server, and data store are independent of one another:
Presentation Tier: This tier is responsible for all user interaction; it is sometimes referred to as the Client Tier.
Service Tier: This tier is the middle tier that encapsulates the application’s business logic. The Service Tier processes requests from heterogeneous clients while interfacing with various backend systems including data stores. This tier is sometimes referred to as the Server Tier.
Enterprise Information System (EIS) Tier: This tier represents those systems that provide and/or store data such as legacy applications and databases. The EIS Tier is sometimes referred to as the data store.
For the patient and administration applications of MedRec, we developed Web applications (webapps) to expose services to their respective users. The webapps follow the Model-View-Controller pattern where Java Server Pages render the View to the user, the Model encapsulates the data presented to and captured from the user, and the Controller is the mechanism that manages the interaction of these components in addition to interfacing with the Service Tier. MedRec employs Jakarta Struts to accomplish this pattern.
The Service Tier provides services to requesting clients and manages interactions with backend applications and resources. MedRec’s Service Tier employs the Session Facade pattern to encapsulate business logic and business data. Session Facades simplify the complexity of an application by offering an interface into distributed services. In MedRec, the primary responsibility of Session Facades is to provide data throughput. In the J2EE and WebLogic Server version of MedRec, Sessions Facades are developed as stateless session Enterprise JavaBeans, and data is managed by entity Enterprise JavaBeans.
To interface with external entities, MedRec exposes application functionality through Web services, which allow for dynamic interaction between disparate systems using a series of open standards. By exposing services via Web services, MedRec can provide and accept data to and from independent parties, therefore achieving the primary goal of centralized medical record management.
Figure 1 illustrates the high-level architecture diagram of the J2EE and WebLogic Server version of MedRec.
Figure 1: Architecture diagram of the J2EE version of MedRec
To establish that Spring can take advantage of the enterprise features of WebLogic Server, MedRec was rearchitected to replace core J2EE components with their Spring counterparts. We replicated the same functionality as the original version of MedRec with the Spring-based version of MedRec (MedRec-Spring).
The introduction of Spring’s IoC is the most prominent addition to MedRec-Spring. IoC is a powerful principle applied via a container that injects dependencies into configured components. IoC decouples application code from its configuration. For instance, objects are not concerned with their dependencies, so they may focus on their responsibilities. In MedRec-Spring’s case, enterprise resources such as DataSources, JMS services, MBean connections, and peer services are provided to MedRec-Spring’s objects during runtime. Additionally, by migrating resource configuration and referencing outside of compiled code, the application is more manageable to shifts from development-specific resources to production resources and environments that are in between.
To properly employ IoC, we found that an application’s code needs to follow stricter Java programming principles—specifically coding to interfaces. Interfaces, among other things, promote better collaboration because dependencies are lightened and implementation changes are isolated. From an IoC perspective, interfaces allow for the pluggable nature of dependency injection. To take advantage of IoC, MedRec-Spring was refactored so that business objects were coded against interfaces.
In MedRec-Spring, stateless session EJBs were replaced by Plain Old Java Objects (POJO). The strength of stateless session EJBs is their remoting capabilities and transaction management. MedRec-Spring satisfied the remoting requirement by exposing service beans via Spring’s HTTP Invoker architecture. Transaction management was provided by Spring’s transaction abstraction layer. Transaction management exactly mirrors that of the original MedRec because the Spring transaction manager was configured to delegate responsibility to WebLogic Server’s JTA transaction manager.
MedRec-Spring contains most of the original MedRec’s messaging functionality. We employed Spring’s JMS package to simplify some of the mundane tasks such as connection factory and destination lookups. Instead of programmatically obtaining a handle on a queue, Spring provides an object that represents a messaging destination. Like all Spring beans, these object representations—JNDI names, connection factory association, and so on—are configured outside of compiled code.
MedRec-Spring contains application management features. These features interact with WebLogic Server’s domain configuration as well as its runtime domain. MedRec-Spring must act upon WebLogic Server’s MBean Servers, and Spring offers connection management that simplifies the accessibility of MBean Server.
Finally, MedRec-Spring exports its services using Web services. Spring offers a JAX-RPC factory that produces a proxy for a Web service. Similar to other Spring beans, the factory bean is configured outside compiled code, making the application more flexible.
Figure 2 shows a high-level architecture diagram of the Spring-based version of MedRec.
Figure 2: Architecture diagram of the Spring-based version of MedRec
Having compared the architecture of MedRec in both J2EE and Spring environments, we now describe some gems that we gleaned when implementing the MedRec-Spring application:
Use lazy initialization. To implement its IoC container, Spring loads an application context file and creates and caches instances of each configured bean. It’s important to understand that each resource referenced by a Spring bean must be available for instantiation or lookup. For example, Spring’s JMX support provides connections to WebLogic Server’s MBean servers. Since not all MBean servers are activated during deployment, users should use Spring’s lazy initialization and look up services on start-up when deploying resources.
Separate out Spring configuration based on functionality. This allows the application components to load only those contexts that are pertinent to their work responsibilities. The practice also allows testers to change the behavior of the application by replacing one application context—DataSource configuration, for example—with a context that is specific to the test environment.
Encapsulate JDBC DataSource connection pooling via
JndiObjectFactoryBean . Beans that require database interaction may then reference this bean in order to take advantage of WebLogic Server’s DataSource pooling capabilities.
org.springframework.ejb.support for Session and Message-Driven Enterprise JavaBeans . Spring’s
org.springframework.ejb.support provides abstract classes that Enterprise JavaBeans (EJB) may extend. These abstract EJB classes assist development by including standard implementations for EJB lifecycle methods. More importantly, these classes provide mechanisms for loading Spring’s application context, including sharing the context across multiple EJBs and clients and therefore reducing duplication and overhead during EJB initialization.
Leverage hot deployment and WebLogic Server’s split development directory environment. This vastly improves the Spring development experience during integration testing. Hot deployment allows your application to be reloaded without restarting the server. The split development directory environment enables faster development and deployment by minimizing unnecessary file copying. The split development directory Ant tasks help you recompile and redeploy applications quickly without first generating a deployable archive file or exploded archive directory.
Package Spring libraries as application libraries, optional extensions, or server extensions. This allows several Spring applications to share the Spring Framework and reduces the footprint of your application. Not only does this decrease memory usage, but it improves deployment times too.
To help you get the most from your Spring applications deployed on WebLogic Server, we have put together a certified BEA distribution that includes Spring 1.2.5, the MedRec on Spring application, and a host of other goodies. The kit can be downloaded from BEA's distribution Web site free of charge.