Search code examples
javaspringspring-bootdependency-injectionmapstruct

Using Spring bean vs a static instance pattern for Mapstruct


I know that you can use the annotation @Mapper(componentModel = “spring”) to use Spring to manage/inject the mapper dependency. My question is, are there any advantages to this approach vs declaring an instance variable within the mapper class itself:

@Mapper
public interface SomeMapper {
    SomeMapper INSTANCE = Mappers.getMapper(SomeMapper.class);

    SomethingElse mapSomethingToSomethingElse(Something something);
}

...

// Clients using mapper
SomethingElse result = SomeMapper.INSTANCE.mapSomethingToSomethingElse(input);

Solution

  • When using Spring dependency injection to inject mappers, you will end up adding extra constructor arguments/instance fields which is desirable as it makes it more obvious that a class is starting to rely on too many dependencies and should most likely be refactored (eg. think about Sonar's rule 'Too many parameters').

    Another advantage is that since you're registering the mappers as beans in the Spring context, you can leverage the framework capabilities to easily inject dependencies in your mappers, customize all mappers at runtime through the BeanFactoryPostProcessor and rely on all the other framework abstractions that seem fit.

    I'd say since you're already using Spring in your application, there is pretty much no reason to not register the mappers as Spring beans and inject them the DI way rather than turning them into static utils.