Spring Dynamic Factory Bean
In this tutorial, we illustrate how to create a dynamic factory bean in Spring.
Suppose we have a file converter application which converts files based on a specific conversion type selected by the users. Our application would hold several conversion mechanisms and should be implemented in a way that dynamically instantiates the corresponding converter based on the selected conversion type.
1- FileConverterFactory
To prevent using several if/else statements each time we convert a file, we create a dynamic factory bean which instantiates all the converter beans at the startup of the application and saves them in a cached HashMap, each bean paired with its conversion type.
Now each time an application receives a conversion request, it gets the corresponding converter bean from the factory using the requested conversion type.
Our factory bean would look like the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | @Service public class FileConverterFactory { @Autowired private List<FileConverter> converters; private static final Map<String, FileConverter> fileConverterCache = new HashMap<String, FileConverter>(); @PostConstruct public void initConverterCache() { System.out.println("Existing converters are: "); for (FileConverter converter : converters) { System.out.println(converter.getConversionType()); fileConverterCache.put(converter.getConversionType(), converter); } } public FileConverter getConverter(String type) { FileConverter converter = fileConverterCache.get(type.toLowerCase()); if (converter == null) { throw new RuntimeException("Unknown converter type: " + type); } return converter; } } |
Annotating the converters field with @Autowired informs the Spring framework to instantiate all the implementation classes of type FileConverter at the startup of the application.
Annotating the initConverterCache() method with @PostConstruct, instructs the Spring framework to call this method just after executing the @Autowired annotation, this method iterates over the converters and saves them in a cached HashMap called fileConverterCache, each paired with its conversion type.
The getConverter() method is exposed publicly to other classes which need to get an instance of a converter based on a specific conversion type.