26
Jul

Spring Dynamic Factory Bean

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:

@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.