An Interesting Approach to Implement Factory Pattern in Java

using Spring annotations

Swastik Gupta
Nerd For Tech
3 min readJun 27, 2021

--

Conventional factory classes for interfaces in Java require an update on the factory whenever a new interface implementation is added. There are a few ways through which this is usually done, let’s first understand one such popular approach with an example. Here I have created a Vehicle interface which is implemented by a Spring component class — Car,

If you’re wondering about the Setter annotation, it is a Lombok annotation that generates setters for class fields. Now let’s create a factory for this interface,

Here the factory is implemented with a more conventional approach with a register method that each implementing class will use to register itself to the factory, like below,

Do note that VehicleFactory bean will be Autowired by Spring. Here’s the issue with this approach — You always need to register an implementation with the factory, it is one additional manual step which isn’t really contributing to the business logic of the application, but is crucial during execution. If a new Developer writes an implementation of the interface and isn’t aware of the factory, he/she just might forget to register the bean with the factory which will possibly break the application. This also means that the factory is tightly coupled to the interface implementations as adding new ones will require a manual update to the factory. Registering each bean to the factory manually through the constructor can be termed as boilerplate too, as it is repetitive and as said above, doesn’t add to the business logic.

Here’s where the use of annotations come into picture. The core purpose of annotations is to store metadata associated with a class or its components. Can we leverage these annotations to automatically register new beans to the factory without any register method call? Sure we can. Here’s how —

  1. Since we are using Spring framework in these examples, let’s reuse the Component annotation for our purpose.
  2. We will give a name to each annotated class which will be used by our factory to register the bean.
  3. We are going to Autowire all interface implementations, through which we’re going to browse, then read the annotations, and then register them to the factory.

Let’s see it in action. We will update the Car class now with a name configured in the Component annotation,

Now let’s update the factory’s logic to read these annotations and register the corresponding beans to the factory during instantiation,

Again, note that List<Vehicle> will be Autowired during instantiation with a list of Vehicle interface implementations. Let’s understand this statement,

Here, we are iterating through each implementation, and putting it into the factory map with key as the Component annotation’s value, and value as the implementation’s bean itself. This key is used during retrieval to return the correct implementation of the interface.

So here we are, unlike the more conventional approaches for implementing factory pattern which require either an update to the factory class itself or an additional statement of bean registration, this annotation based approach with the Spring framework takes care of it by automatically registering any new implementation with the factory. This not only leads to decoupling the factory from the underlying implementations, but also ensures less boilerplate code in the application.

--

--