Serving the date with Spring
In this example I’ll create a simple Spring project in IntelliJ which will serve the current date. I’ll use multiple implementations (using the old Java Date and new DateTime classes) to demonstrate the 3 stages discussed in my last post on dependency injection.
I’ll build an interface with a
getCurrentDate() method that returns the current date and use the Spring container (which can read xml config files) to provide the implementations.
I’ll begin by creating an IntelliJ Idea Spring project called DateOutputter – check the Spring box when creating the project to add the jar files to the project’s lib folder.
And then I’ll create a package in the src directory called datetoday
Programming to an interface
As described in the previous post the first step to avoiding coupling is to program to interfaces. In this project there is only one public method required – the method that returns the current date so this should be specified by an interface. I’ll also create one of the implementations in the package so I can see the output.
Note that in the implementation I’ve provided a set method rather than instantiating the Date object in the class directly so as to be able to demo the some features of the Spring container.
Adding the container config
To add a Spring configuration file, create a file called
application.xml at the root of the
src directory. We will use this later when constructing the client to build an “application context”. A Spring class called
ClassPathXmlApplicationContext reads the file and uses the data to form the container.
Intellij will warn you that the application context is not configured for this file – click the link to correct this (i.e. to have IntelliJ recognise it as a Spring config file)
and then choose New Application Context from the drop down and click Ok on the dialog box.
Now the container is ready to use I can specify the date I want to inject into the bean. I want to inject an instance of a
java.util.Date object to the
DateTodayOldImpl class so I use the bean tag to specify the class and the property tag to identify the field. Note that although the field is called “today” the method is called setDate so the reference is to date (as derived from removing the set and converting the capital D to a lower case d).
Adding a client
Rather than use a web client, I’ll create a standalone client for demo purposes in a package called dateclient (MIGHT CHANGE THIS LATER). The client will contain a main method which will use the Spring container (which in turn will read from the appliation.xml config file) to collect an implementation of the
DateToday interface and will call its
getCurrentDate() method and print the result.
At this point I can run the client and will get today’s date output.
I have a functional date service which will run quite happily UNTIL Java’s designers finally realise how awful their Date implementation is and rewrite it based on Joda-Time. So time to update my application with the shiny new JSR 310 classes.
In my datetoday package I shall write a new implementation, update my configuration file and not do anything to my clients and from that point forward clients will use the new service without any need for updating or (on the client side) recompiling.
Now I have a new implementation I can use it just by changing the configuration file.
Note the simpler implementation here – nothing to stop me from using this with the old Date class but I wanted to demonstrate the injection process with a set method. So running this displays the date as before (well apart from format differences) with no changes on the client side.
So this post demonstrates the use of Spring to implement the 3 elements discussed to reduce coupling:
- Programming to interfaces
- Dependency injection
- Central configuration (via a container)
These come together in the client code: