Tips and Tricks of Dependency Injection in Spring

Introduction

This is a series and it would make a lot of sense if read in a sequence. You can find all the posts under the heading “Spring Beginners to Professionals“. In this post, we will discuss few more tips and tricks of dependency injection in Spring.

There are different types of objects and primitive values which qualify to get injected into a bean. As a developer and architect, it is important for us to understand all these concepts. Here, in this post, we will try to discuss the ones which are frequently used.

Injecting Primitives and Strings

Beans can have properties which are of primitive type or simply strings. In such a case, while injecting these properties, they are specified in the value attribute of a property element or constructor-arg element.

All these values are specified as simple String literals, but they are converted to their actual expected types while injecting by a conversion service.  If you want to set a null value to any of the properties, then spring provides a <null/> elements for the same.

Injecting Complex Objects

Apart from the primitives and strings, there are objects like Properties, Collection and custom objects. These are specially handled and Spring provides mechanism for most of them.

Injecting Properties Objects

Properties object can be injected in any bean in two ways. They can be supplied in a value element as name value pairs, one per line as shown in the example here.

Another way of injecting properties is to use the props element as shown in the example here:

You can use this for injecting Properties object in constructor arguments as well.

Injecting Collections

In a similar fashion you can also inject the members of the Collection framework. The List, Set and Map etc. Remember these are not typed collection, so you can have heterogeneous values for each element in the collection.

For e.g.: A List can contain elements of type String, Integer, Arrays,  another bean reference at the same time and other collections at the same time.

In the XML you can inject values to this property using the list element from the beans schema.

This is an example of injecting a heterogeneous list using setter injection. You can also do the same using constructor injection. If you bootstrap the application and try to print the values of the list contained in the oCollection bean, you will get them all.

In a similar way, you can inject Maps, Sets and Arrays as well. You will end up replacing the list element with the map, set or array respectively.

However, the map demands a sub element with the name entry, which is analogous to the Map.Entry class in Java. The entry must have a key element which can contain plain strings or any other object. And the value can contain absolutely anything.

You can similarly auto-wire the collections or arrays in the constructors or setters, in the annotation driven configuration.

A Word About Strongly Typed Collections

After introduction to the concept of Generics in Java 5, you can define typed collections which allows you to associate a type information with the collection. This provides you compile time safety and helps in avoiding errors, which could have otherwise surfaced at the run time.

If you need strongly typed collection and want to get all the benefits of Generics in Spring injections, then you are in luck. Spring offers it with the help of its Conversion Service infrastructure and Java’s reflection feature. At the time of injection, all the type information is available to Spring Container. More on the conversion service in upcoming posts.

Injection Using Compound Property Names

Another interesting feature is injection using compound property names. Consider a class Order, which has a property of type orderAmount which in turn contains a property named price of type float. You can inject a value for the price property of OrderAmount in the bean metadata of Order. Which looks something similar to the code here.

and the XML configuration may look like the one below:

The only condition being, none of the intermediate properties is null, else will result into a NullPointerException.  Compound property name injection is a rare thing and we do not use it in practice if Spring manages all the beans in the application.

However, if we are dealing with some third party code where we do not have flexibility of injecting everything through Spring, there can be opportunities to use it.

Few more ways of Injection

Another recommended way of injecting a bean into another bean is using the idref element. It allows deploy time validation of the bean id for existence. This is good because the mis-configuration is detected much early in the cycle.

For some additional read you can also look at p namespace and c namespace in Spring Dependency Injection. However, they are rarely used, but I find them to be convenient ways of injecting bean properties.

Summary

Today we discussed about injecting different types of objects and primitives into Spring beans. This is definitely not the complete list, but yes it helps you get started and covers the most frequently used ones.

There is one more form of dependency injection which is also known as Interface injection. You can definitely look at Martin Fowler’s blog for the same.

For more on Spring, stay connected.