Spring-style builder pattern
By: Patryk Ziobroń
Tags: Builders, Software Dedign Patterns, Spring Framework, Spring, Objectfactory

The builder pattern is one of my favourite software design patterns. It’s easy to use and highly understandable (You will find a great article about this pattern here).

However, when it comes to Spring Framework, there is one thing that I found problematic in the classic form of this pattern — the lack of ability of autowiring beans.

Sometimes, it would be handy to make use of some existing method from the other Spring bean (service), to generate a specific piece of data, directly in the object builder.

Let’s say we would like to calculate the distance between 2 cities.

To do that, we need the POJO of the city:

and the DistanceService that is responsible for calculating the distance between 2 points (a and b):

We also need to retrieve the city coordinates by using some dedicated service like this one:

It would be nice if the service above could be used when constructing the city object, directly in the builder. We could easily achieve that by using the prototype scope and the Spring ObjectFactory class.

First, we need to create the builder class according to the classic builder pattern (CityObjectBuilder):

There are some differences from the typical builder:

@Component annotation — defining the Spring bean

annotation — defining the Spring bean @Scope annotation — the prototype scope annotation which means that the new object of this class will be instantiated each time the bean is requested through the Spring Framework

annotation — the prototype scope annotation which means that the new object of this class will be instantiated each time the bean is requested through the Spring Framework The autowired GeoLocationServcie — the CityObjectBuilder bean is in the control of the Spring Framework so it is possible to autowire the other Spring services/beans here

— the bean is in the control of the Spring Framework so it is possible to autowire the other Spring services/beans here there are 2 ways of creating the builder: inside the class being built and as a separate builder class; I’ve chosen the second approach as usually I operate on the JAXB classes which are generated automatically from the XML schema and I cannot modify them easily

Now, we need to create the builder Spring service (CityBuilder) that makes use of the CityObjectBuilder in the following way:

The builder class above is a singleton service (per Spring application context) but ObjectFactory feature guarantees that the objectBuilder method returns the object within the scope defined in the CityObjectBuilder class.

The CityObjectBuilder bean has a prototype scope defined which means that the new object of this class will be instantiated each time the bean is a accessed — in this specific example in every invocation of the objectBuilder() method. The GeoLocationService is used in the CityObjectBuilder to retrieve the coordinates of the city — we can autowire more beans and make use of them directly in this builder :)

As a result, we can easily construct the city objects by using our Spring-style builder pattern and calculate the distance between them:

It is arguable if services like the GeoLocationService should be used directly in the object builder (instead of invoking it outside of the builder and populating the data of the City object). I believe it depends on the situation (whether the services/beans used inside the builder are internal or external, is it acceptable to build the object in the case of failure of the embedded service in the builder or not etc.).

Nevertheless, I find this solution pretty useful in many scenarios and what is more, I strongly believe that such a great framework like Spring should never restrict the possibility of using well-known software design patterns, like the builder pattern!