, ,

One of the things I wish to do on this blog is show you realistic examples of using the Spring Framework in Enterprise Application Development. The Spring Framework is very popular for building large scale applications. When you build a ecommerce website that might have 50,000 users on it at any given time the scope of the application you are building changes. This type of site quickly outgrows the traditional 3 tier architecture (web server / app server / database server). The ‘website’ is no longer a simple war file being deployed to Tomcat. You have a data center, with a small server farm. Load balancers, application clusters, message queuing, ‘cloud computing’, micro services. The Spring Framework was not only built for this type of application environment, it thrives in it.

Environments

When you start developing enterprise class applications, you will need to support multiple deployment environments. You’re no longer going to be testing code on your laptop, then deploying it to the production server. Frequently in the enterprise, as a developer you won’t even have access to the production environment. Companies which need to comply with regulations such as SOX, PCI and/or SAS-70 will have specialized teams which will manage code deployments to their testing (QA/UAT) and production environments. This is known as segregation of duties. A very common business practice. From my personal experience it is more stringent in large financial enterprises than it is in retail organizations. Less so in smaller companies because they simply don’t have the resources to support specialized IT staffs.

More modern development cultures will be performing CI builds and automated deployments. Teams on the bleeding edge of modern software development might even be doing continuous deployments I feel continuous deployment is probably the holy grail of software engineering, but in reality it is as rare as a great white buffalo in the wild. I do hope to see more organizations adopt continuous deployments, but it does take a very disciplined organization to get there.

Each of these environments will have its own configuration needs. As the scope of your application grows, chances are the uniqueness of each environment will grow too. The Spring Framework has some outstanding tools which are used to manage the complexities of modern enterprise application development. First, let’s consider some common challenges in the types of environments you will need to support in a large enterprise application.

Local Development

This is your development environment, running from your laptop. This is an area I often see companies absolutely fail at. Your code should be able to run locally, without the need to connect to other servers in the enterprise. Ideally, you should be able to run the code on a plane at 30,000 without a wi-fi connection.

This means:

  • You cannot use an external database. You’re not going to use the Oracle development database.
  • No interaction with other web services.
  • No JMS (MQ Series, Active MQ, Oracle AQ, etc)
  • Your build artifacts need to be locally cached (hello Maven, Ivy!!)

The Grails team does an outstanding job of supporting a local development environment of of the box. When you run Grails in dev mode, it will automatically create an in memory H2 database. Hibernate is used to generate the database tables based on your domain classes.

Continuous Integration

Continuous Integration servers can be tricky little beasts to configure for because of the different types of testing software they accomodate. You may have a project the produces a JAR file, which only has unit tests which will zip right along. You may have integration tests, like Grails does, which bring up an embedded Tomcat instance an H2 in-memory database. Your tests might even perform functional tests using something like Spock and Geb to interact with the embedded Tomcat instance. Its also not uncommon for CI servers to have automated deployment jobs – to another specialized environment.

Each of these scenarios is likely to drive special configuration needs into your application.

Development

Some companies elect to have a development environment. This is typically a production like server environment that the development team has control over. When you deploy into this environment, you will need to configure the application to interact with servers within that environment.

QA / UAT

QA or “Quality Assurance” and UAT “User Acceptance Testing” are environments for non-developer resources to test the software. In some organizations you may have both QA and UAT, or you might have one or the other. If you have both, chances are the organization has formal QA Engineers which work with the QA Environment, and Business Analysts which work with the UAT environment. These environments are often managed by a configuration management team. Sometimes developers will have access to the environment, but often they will not.

Pre-Production or Stage

Pre-Production or Stage (Staging) is an application environment that works with all the production services and supporting databases. This is an environment that allows the deployment of application code, but limits the access to that code. For a website, you might see a special url or access restricted to specific IPs, or throttled by load balancers.

This environment is not as common, but some organizations use it. Facebook deploys code something along this line.

Production

Production is the environment you end users will utilize. This is the main transactional environment and the one your business partners wish to keep operational at all times.

Summary

You can see each of these environments will have its own unique requirements. You’re going to have different database servers, different database versions, often different database vendors. You’ll have different supporting services. For example in an ecommerce website, you might have a payment gateway. In dev, it might be a mock, in test you might be using a testing gateway supplied by your payments provider, and then a different payment gateway for production.

Spring Framework Multi-Environment Support

The Spring Framework was developed from the ground up to support the challenges of supporting complex enterprise environments. You have a number of mature features in the Spring Framework to use in supporting the challenges of enterprise class applications.

Properties

The Spring Framework has excellent support of externalizing properties. “Properties” are simple string values which are externalized from your application. In the Spring Framework properties can be set the following ways:

  • In a traditional properties file. This is typically kept in the resources folder and is often named ‘application.properties’. It is by convention to use <filename>.properties.
  • Using Operating System Environment variables. Java can read values set in the Operating System as environment variables. I’ve used this in the past for things like database settings, which worked out nicely. In this case, my build artifact was easily portable between environments. Once setup, it was effectively ‘drag and drop’ for the support staff.
  • Command line variables. When starting any Java application, you have the opportunity to pass command line variables into the program. This is a handy way to make your build artifact portable. One word of caution, when examining running processes on a system, you can sometimes see the command line information which started the process. So this solution may not be the best option for password strings.

The Spring Framework Support has a number of options for sourcing in property values. One way is using the Spring Expression Language (SpEL). You can see some examples of this in my recent post here.

Dependency Injection

Changing property values is great for things like connecting to a different database server. But often in enterprise class applications you will need behavioral changes which are beyond simple property changes. One of the core features of the Spring Framework is the support of Dependency Injection. Once you become accustomed to development with Dependency Injection with in the Spring Framework, you will see how your code becomes more modular. Your classes will naturally adhere to the Single Responsibility Principle. If you’re doing Dependency Injection against Interfaces, it becomes very easy to swap out components.

Let’s say you have an application which needs to send a JMS message on an event such as a customer purchase. This may trigger an email to the customer about their order, and the data warehouse group might want the purchase information for their analytics. For your unit tests and your integration tests, you might be using Mockito to provide a mock. In your deployed environments you might be using the corporate standard of MQSeries for messaging. But what about doing CI builds? An embedded instance of ActiveMQ just might be perfect solution.

So, in summary, this example has:

  • A Mockito Mock object;
  • 3 different MQ Series configurations;
  • And embedded ActiveMQ.

The MQSeries configurations are easy to handle with property settings. The only thing changing here are the connection parameters. This is the perfect use case for externalized properties.

For your unit tests, if you want to keep them true unit tests (as I defined here), you’ll need to manage the dependency injection yourself. Testing frameworks such as Mocktio and Spock make this easy to do.

If you’re performing integration tests an easy way to manage the Spring Context is through configuration composition. But you may wish to favor using Spring Profiles instead. Each is easy to use, as I explain in the sections below.

Configuration Composition

Inexperienced Spring developers will place all their configuration into single xml files or configuration packages. This is often a mistake since it limits your configuration options. In our example, all of our configuration options could be supported through configuration composition. You would need to place each configuration into a separate xml file, or configuration package. Then selectivity import it into a parent configuration. You basically import the configuration you wish to use into a parent configuration, then load the parent into your Spring Context at run time. This is still a very popular technique to use for testing where it is very easy to specify the Spring context to use at runtime.

For a long time this was the only option Spring developers had to use. In Spring 3.1, Profiles were introduced to help manage different configurations. As you’ll see in the next section this a very powerful feature of Spring.

Spring Framework Profiles

Spring Profiles is a very powerful feature introduced in Spring Framework 3.1. Profiles allow you to define Spring Beans and specify when they should be loaded into the context.

If you do not mark your Spring Been with a profile, it will always be loaded into the Spring Context.

When you do mark your Spring Bean with a profile, then that profile must be set to active for that bean to be loaded into the Spring Context. This makes management of the environment easy, since you can simply mark the different options with the appropriate profile, then when you set that profile option to active, Spring will wire up the appropriate Spring Beans into your application.

There is one special profile that is rather poorly documented, but very nice to use. And that is the default profile. When you mark a Spring Bean using default , this bean is loaded into the context only if no other profile has been set to active. If it there is an active profile, Spring will attempt to find a bean matching that profile first.

What I like about using this option is you don’t have to set an active profile in production. While this is easy to use, from experience it can cause some friction and confusion with the configuration management team. Through the use of default profiles, your application can be deployed into production without an active profile being set.

Going back to the example we’ve been using, I would probably use a CI build profile for the CI build where I wanted to use an embedded instance of ActiveMQ, then setup the MQSeries option using the default profile. Having control over the CI build environment it’s easy for me to specify an active profile, so my CI build profile objects will get loaded into the Spring context. When my example application gets deployed elsewhere, no profile is set to active, so the default profile objects with the MQSeries configuration get loaded into the Spring Context. While we are supporting 3 different environments with MQSeries, this can be managed (and should be) with properties. This is because the MQSeries objects remain the same, except for the configuration of the environment the application is connecting to.

Conclusion

As an application developer, the Spring Framework offers you a lot of options on how you can compose your application. If you’re used to smaller scale development, the plethora of configuration options in the Spring Framework will probably seem like overkill to you. Why would you need such flexibility? Right? No, Wrong. As I’ve shown here, when developing applications in the enterprise you are going to be challenged with supporting the needs of many different environments. You are not just developing code on your laptop. No longer is the production environment the only environment you need to be concerned with. In a large enterprise you will need to support multiple environments, with different configurations and different needs. The Spring Framework has evolved over the years to support the challenging needs of enterprise application development. It’s no wonder that the Spring Framework is the most popular framework to use for developing enterprise class Java applications.

0
Share

Introduction

Spring 3 introduced the Spring Expression Language (SpEL) which has a syntax similar to Unified EL. It can save you a lot of coding, because you can dynamically assign values at runtime.

The folks at Spring, made the Spring Expression Language part of what is considered ‘Spring Core’. Thus, the Spring Expression Language is available for use throughout the Spring Framework.

Spring Framework Overview

SpEL can be configured through files and bean classes using XML and respectively Java annotation.

Spring Expression Language Examples

Project Setup

In this introductory course we will demonstrate how to use SpEL with XML and annotation based configuration to implement a simple example.

The @Component  annotation is used to register the component in Spring. Here are two components annotated correspondingly :

 

We run the application using the App class.

In the first step:
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
we create an application context using ClassPathXmlApplicationContext which loads the configuration from bean file which is located in class path of the application.
Subsequent steps load the beans (in our case Employee and Company) from the context.
In the end: context.close() the ConfigurableApplicationContext.close() will close the application context, releasing all resources and also destroying all cached singleton beans.

where applicationContext.xml content is:

The applicationContext.xml can enable the auto component-scan to avoid bean declaration in XML file:

Once we created source and bean configuration files, let us run the application. The output will be:

Employee James Smith in Acme Company company and department Information Technology

Project Dependencies:

For a Maven project the pom.xml file is:

Annotation-based configuration

The @Value  annotation allows to specify a default value by placing it on fields, methods and method/constructor parameters. College.java:

Student.java:

after we add in App class the lines:

and run again we will get as result:

Student James Smith from Eastern Florida State College with a Computer Science major

What is actually happening :

1.Beans definitions are loaded
This means scanning the application context XML files, the packages defined by component-scan, and loading the bean definitions found into the bean factory.

2.The beans are instantiated and stored in the application context
The bean factory creates each bean from the bean definitions, while the bean dependencies get injected.

3.The beans are post processed
All initializing methods declared in the XML method will be executed, while Annotations will be validated.

XML Based Configuration

Literal Values

We used literal values to bean properties:

Any data type can be used.

Bean Reference

we can refer other spring beans using SpEL:

which can be also written:

The outcome from both the above expressions is same.

Property references

We can use literal values to bean properties using SpEL:

for a nested property value a period (.) is used

for which is the same as:

Method references

are the way a method references another bean:

on which we can use operator for example:

To avoid a NullPointerExeception we should use the Safe Navigation Operator “?.”:

SpEL Predefined Variables

In SpEL “systemProperties” and “systemEnvironment“ are part of a Environment bean which provide information at runtime (late binding):

systemProperties that contains the environment variables on the machine where the application is running.
systemEnvironment – that is retrieving environment specific properties from the runtime environment, more specifically Java properties that we set in Java when the application started (using the -D argument)

Let’s first define an environment variable appHome with the value: C:/somePath and see how to make it available through SpEL.

After we autowire the Environment object in the current Spring container and we use the injected parameter by @Value  in an instance variable of the class we have the environment variable we looking for.

Running it:

will give the same result: environment variable value appHome = C:/somePath as:

where in the configuration.properties file (under resources directory) we have defined: appHome=C:/somepath

In this example we used @PropertySource  annotations to read properties file, annotation placed on core Spring configuration classes ( @Configuration ).

Conclusion

The Spring Expression Language is a powerful feature of a the Spring Framework. As you develop enterprise class applications in Spring, you will frequently encounter uses for the Spring Expression Language. A very common use for the Spring Expression Language is in defining your database settings. In a typical enterprise, you will have a development environment, a QA or testing environment, and your production deployment environment. The database server and settings will be different for each of these environments. The Spring Expression Language makes it easy to externalize your database properties.

Get the code!

Source Code

The source code for this post is available on github. You can download it here.

0
Share