【问题标题】:How to inject(custructor) a spring bean into abstract mapper of Mapstruct?如何将spring bean注入(custructor)到Mapstruct的抽象映射器中?
【发布时间】:2019-10-18 13:10:11
【问题描述】:

我有以下映射器类,我想在其中使用CounterService。我正在尝试构造函数注入,但这不起作用,null 正在打印。

@Mapper(componentModel = "spring", uses = CounterService.class, injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public abstract class CarMapper {

    private CounterService counterService;

    public CarMapper(CounterService counterService) {
       this.counterService = counterService;
    }

    public abstract Car dtoToEntity(CarDto carDto);

    public CarDto entityToDto(Car car) {
        System.out.println(counterService)
        //....
        return carDto;
    }

}

mapStruct的实现类

@Component
public class CarMapperImpl extends CarMapper{

  @Override
  public Car dtoToEntity(CarDto carDto){
    //...
  }
}

如果我使用@AutoWired 使用字段注入,那么它可以正常工作。这意味着 Spring 不支持 abstract 类的构造函数注入。是不是因为abstract类不能直接实例化,需要子类来实例化?
有什么办法mapStruct可以在实现类中创建一个构造函数:

  public CarMapperImpl(CounterService counterService){
    super(counterService);
  }

这样,构造函数注入应该可以工作。

【问题讨论】:

    标签: spring spring-boot mapstruct


    【解决方案1】:

    这与 Spring 无关。不使用超级构造函数是 MapStruct 团队深思熟虑的决定。

    你可以做的是使用setter注入。

    @Mapper(componentModel = "spring", uses = CounterService.class, injectionStrategy = InjectionStrategy.CONSTRUCTOR)
    public abstract class CarMapper {
    
        private CounterService counterService;
    
        public abstract Car dtoToEntity(CarDto carDto);
    
        public CarDto entityToDto(Car car) {
            System.out.println(counterService)
            //....
            return carDto;
        }
    
        @Autowired
        public void setCounterService(CounterService counterService) {
            this.counterService = counterService;
        }
    
    }
    

    【讨论】:

    • 如何在 Spring 中使用这个映射器?通过将接口更改为抽象类?
    • 你只需注入映射器。实现用@Component注释
    【解决方案2】:

    您还可以使用如下所示的 Mapper 装饰器。另外,请务必检查生成的类。

    @DecoratedWith(CarDecoratorMapper.class)
    @Mapper(componentModel = "spring")
    public interface CarMapper {
    
        Car dtoToEntity(CarDto carDto);
        CarDto entityToDto(Car car);
    
    }
    
    public abstract class CarDecoratorMapper implements CarMapper {
    
        @Autowired
        private CarMapper delegate;
    
        @Autowired
        private CounterService counterService;    
    
        public Car dtoToEntity(CarDto carDto) {
            Car car = delegate.dtoToEntity(carDto);
            car.setProperty(counterService.count(carDto));
        
            return car;
        }
    
        public CarDto entityToDto(Car car) {
            CarDto carDto = delegate.entityToDto(car);
            carDto.setProperty(counterService.countDto(car));
    
            return carDto;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-12-29
      • 2020-07-07
      • 2016-04-06
      • 1970-01-01
      • 2023-01-15
      • 1970-01-01
      • 2023-01-31
      • 1970-01-01
      • 2018-06-30
      相关资源
      最近更新 更多