mapstruct

Mapstruct constructor injection (spring)


In MapStruct 1.3.0.Final, we have dependency injection via constructor. Documentation says:

The generated mapper will inject all classes defined in the uses attribute

(...)

For abstract classes or decorators, setter injection should be used.

I have the following example:

    @Mapper
    public abstract class VehicleMapper {
    
        @Autowired
        private CarMapper carMapper;
        @Autowired
        private BikeMapper bikeMapper;
    
        @Override
        public VehicleDTO toDto(final Vehicle source) {
    
            if (source instanceof Car) {
                return carMapper.toDto((Car) source);
            } else if (source instanceof Bike) {
                return bikeMapper.toDto((Bike) source);
            } else {
                throw new IllegalArgumentException();
            }
        }
        (...)

So, in my case, it should look like this (componentModel defined in maven):

    @Mapper
    public abstract class VehicleMapper {
    
        private CarMapper carMapper;
        private BikeMapper bikeMapper;
    
        @Autowired
        public void setCarMapper(final CarMapper carMapper) {
            this.carMapper = carMapper;
        }
    
        @Autowired
        public void setBikeMapper(final BikeMapper bikeMapper) {
            this.bikeMapper = bikeMapper;
        }
        
        @Override
        public VehicleDTO toDto(final Vehicle source) {
    
            if (source instanceof Car) {
                return carMapper.toDto((Car) source);
            } else if (source instanceof Bike) {
                return bikeMapper.toDto((Bike) source);
            } else {
                throw new IllegalArgumentException();
            }
        }
        (...)

Question:
So, is it not possible to inject carMapper and bikeMapper via the constructor? Does injectionStrategy = CONSTRUCTOR work only for classes declared in @Mapper(uses = {})?


Solution

  • I think that injectionStrategy = CONSTRUCTOR works on the interface that has the @Mapper annotation. I don't think it works with abstract classes. I'm sure it will not work when you define your own fields (instance variables). How would MapStruct know what user defined fields to initialise in the constructor?