Spring Tutorial – Starting with Spring JavaConfig

Remember Sharing is caring! So if you get something from this Spring tutorial please share it with others on facebook, google+, LinkedIn,Twitteretc… so it may help them too!

There’s an area of the Spring Framework that has gained a lot of traction in the past couple of years, its called Spring JavaConfig

So, what is Spring JavaConfig ?

Spring JavaConfig can be thought of as an XML configuration equivalent, only written in Java code!

This may sound odd to begin with because as we often talk about and try to externalize or decoupling ‘stuff’ away from our Java applications, usually into files of various formats; i.e. XML or properties files… but now we’re talking about taking ‘stuff’ out of files and putting it back into our Java Code! Why?

There’re a couple very good reasons really, when we stop and think about. It really depends upon what ‘stuff’ is being move back into your Java code.

Spring JavaConfig provides us with a great way to configure our Spring enabled Java applications without getting tangled up in “XML hell”, while at the same time keeping the “decoupling” advantages of XML (i.e. separate the configuration “stuff” from the actual application code) and gain the advantage of Java compile time checks!

Have you ever been in that position where you’ve built a large spring enabled Java application successfully to find you made a silly typo in the configuration. Only to show itself when the code is sent off for testing or worse a demo… ouch!! Spring JavaConfig would nail these types of problems by failing fast at compile time, nice! Also, personally I prefer to read Java code any day of the week, rather cryptic XML namespaces.

So how does it work ?

In this Spring Tutorial I want to start looking at how we go about wiring a very basic application using Spring JavaConfig. We will look at what classes will contain our configuration code, how to load our new configuration class and take a look at how can we can inject beans into other beans using this approach.

Let’s start by looking at what replaces the trusted XML configuration file. Well there’re no surprises that it’s a Java class. Yes, just like any other POJO but with the added annotation of;

@Configuration

So the most basic configuration class would look like;

@Configuration

public class AppConfig {

}

(I would recommend suffixing the class name with ‘Config’, just to help readability in the code base but that’s only preference.)

The basic class above is the same as having an XML file called AppConfig.xml. It follows then that we can put our bean definitions into this class! Let’s try an example;

@Configuration

public class AppConfig {

@Bean

public Bar bar() {

return new Bar();

}

}

We now have our first bean definition within our first Spring JavaConfig configuration class.

The method bar() returns an instance of the Bar class.

Note, the annotation of @Bean. This tells Spring that the method is a bean definition. When JavaConfig sees this annotation it will execute the method and register the return value as a bean in a BeanFactory.

Also, remember the ‘id’ or ‘name’ attribute in the <bean> XML element, well the method name replaces that and acts as the bean ‘id’.

So, how do we wire beans with dependencies with other beans ?

It’s as simple as having a method calling another method! Yes it’s that straight forward!

Let’s expand our example;

@Configuration

public class AppConfig {

@Bean

public Foo foo() {

return new Foo();

}

@Bean

public Bar bar() {

return new Bar();

}

}

We now have 2 method annotated with the @Bean

bar() returns an instance of Class Bar

foo() returns an instance of class Foo

This gives us two bean definitions now; for class Bar and class Foo.

However, if we have a dependency between the two, how can we wire the two instances together manually. (note: NOT using autorwiring.)

In XML, we would have used either constructor or setter injection, well we can use the same principle in Spring JavaConfig.

If Foo has a dependency of Bar, we can inject Bar using constructor injection, by just calling the bar() method;

(Remember you will need to implement the constructor in the Foo class and have an instance variable to contain it, just as you would if you used XML for the configuration.)

return new Foo(bar());

Now the two beans will be wired together.

It’s worth noting that because our methods are annotated with @Bean, some spring magic goes on behind the scenes.

As an example, we modify our code so we have two methods which construct Foo instances, both injecting bar()

i.e;

@Configuration

public class AppConfig {

@Bean

public Foo foo() {

return new Foo(bar());

}

@Bean

public Foo foo2() {

return new Foo(bar());

}

@Bean

public Bar bar() {

return new Bar();

}

}

How many Bar instances would we have ?

As with XML configuration, the Spring JavaConfig default scope is singleton, so we would have just the one instance of Bar in the Spring container, even though “return new Bar()” is called twice!

This magic occurs because the class AppConfig is annotated with @Configuration, telling spring to proxy the class, so it can manage the beans created inside it. Now because of this the AppConfig class cannot be made ‘final’ and doing so would result in an exception being raised. Another side effect is that the class will always require a no argument constructor, in other words if you create a constructor with an argument, you will also need to create a constructor with no arguments, previously Java created it for you automagically.

We can alter this default behaviour by simply changing the ‘scope’ of the method bar() with the @Scope annotation (org.springframework.context.annotation.Scope) and provide it with the “prototype” string.

Now each call of method bar() will result in a new instance of Bar being created.

@Bean

@Scope(“prototype”)

public Bar bar() {

return new Bar();

}

From the previous example of foo() and foo2() we would now have two instances of Bar being created!

To wrap up this first tutorial on Spring JavaConfig, how do we load the configuration of our new configuration class ?

When working with XML configuration we rely on the ClassPathXmlApplicationContext, org.springframework.context.support.ClassPathXmlApplicationContext

now with Springh JavaConfig we use a different class; AnnotationConfigApplicationContext, org.springframework.context.annotation.AnnotationConfigApplicationContext

in our simple Java client class, which is currently dependent on XML.

final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(“/spring/AppConfig.xml”))

That changes now to;

final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class)

About the author:Bruce is a techie, a gadget geek, programmer, mentor and all round technology nut. He holds two degrees in computer science, with over 25 years in the software business. Currently working freelance as a software engineer and programming mentor. He loves what technology can do for us. Building applications using functional, Object Orientated languages & polyglot persistence helps him reconnect with the feeling of building something tangible.
To learn more about Bruce, follow him on
Twitter @denofprogram