@Service Class 未在 org.mapstruct 中自动装配。@Mapper Class
@Service Class Not Autowired in org.mapstruct.@Mapper Class
我正在尝试使用 MapStruct 将 json 序列化添加到我的 SpringBoot 应用程序。 @Mapper class 使用@Service 添加一些“aftermapping”逻辑。问题是,这个@Service class 不是自动装配的。
这是我的映射器class:
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = "spring")
public abstract class InstrumentMapper {
protected MarketDataService marketDataService; // is @Service
@Mapping(target = "marketCode",
expression = "java(instrument.getMarket().getCode())")
public abstract InstrumentDto fromInstrument(Instrument instrument);
public abstract List<InstrumentDto> fromInstruments(List<Instrument> instruments);
@Mapping(target = "market",
expression = "java(marketDataService.findMarketByCode(instrumentDto.getMarketCode()))")
public abstract Instrument toInstrument(InstrumentDto instrumentDto);
public abstract List<Instrument> toInstruments(List<InstrumentDto> instrumentDtos);
@Autowired
public void setMarketDataService(MarketDataService marketDataService) {
this.marketDataService = marketDataService;
}
}
当调用 toInstrument
方法时,应用程序因 NPE 而失败,试图 marketDataService.findMarketByCode(instrumentDto.getMarketCode())
。
希望这些信息足够了。如果还需要什么,请告诉我。
提前致谢!
更新:
市场数据服务class。它通过@Service注解添加到上下文中。
@Service
public class MarketDataService {
@Autowired
private InstrumentRepository instrumentRepository;
public Instrument findInstrumentByCode(String code) {
return instrumentRepository.findFirstByCode(code);
}
public List<InstrumentDto> getAllInstrumentDtos() {
List<Instrument> instruments = getAllInstruments();
List<InstrumentDto> dtos = Mappers.getMapper(InstrumentMapper.class).fromInstruments(instruments);
return dtos;
}
public void updateInstrument(InstrumentDto instrumentDto) {
Instrument instrument = findInstrumentByCode(instrumentDto.getCode());
if (instrument == null) {
throw new IllegalArgumentException("Market with given code not found!");
}
instrumentRepository.delete(instrument);
instrument = Mappers.getMapper(InstrumentMapper.class).toInstrument(instrumentDto);
instrumentRepository.save(instrument);
}
}
算法如下:@Controller class 获取 PUT 请求并使用请求的主体(instrumentDto 参数)调用 MarketDataService.updateInstrument 方法。后者调用了相同参数的toInstrument方法
你有 NPE 的原因是因为你正在使用 MapStruct Mappers
工厂作为非默认组件模型。
Mappers
工厂不执行任何依赖项注入。
您必须在 MarketDataService
中注入映射器。这样做时要小心,因为你有一个循环依赖。
除此之外,您在 Mapper 中使用的模式并不是真正正确的模式。当简单的 source
就可以时,您正在使用表达式。
例如
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = "spring")
public abstract class InstrumentMapper {
protected InstrumentRepository instrumentRepository;
@Mapping(target = "marketCode", source = "market.code")
public abstract InstrumentDto fromInstrument(Instrument instrument);
public abstract List<InstrumentDto> fromInstruments(List<Instrument> instruments);
@Mapping(target = "market", source = "marketCode")
public abstract Instrument toInstrument(InstrumentDto instrumentDto);
public abstract List<Instrument> toInstruments(List<InstrumentDto> instrumentDtos);
protected Instrument findInstrumentByCode(String code) {
return instrumentRepository.findFirstByCode(code);
}
@Autowired
public void setMarketDataService(MarketDataService marketDataService) {
this.marketDataService = marketDataService;
}
}
我正在尝试使用 MapStruct 将 json 序列化添加到我的 SpringBoot 应用程序。 @Mapper class 使用@Service 添加一些“aftermapping”逻辑。问题是,这个@Service class 不是自动装配的。
这是我的映射器class:
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = "spring")
public abstract class InstrumentMapper {
protected MarketDataService marketDataService; // is @Service
@Mapping(target = "marketCode",
expression = "java(instrument.getMarket().getCode())")
public abstract InstrumentDto fromInstrument(Instrument instrument);
public abstract List<InstrumentDto> fromInstruments(List<Instrument> instruments);
@Mapping(target = "market",
expression = "java(marketDataService.findMarketByCode(instrumentDto.getMarketCode()))")
public abstract Instrument toInstrument(InstrumentDto instrumentDto);
public abstract List<Instrument> toInstruments(List<InstrumentDto> instrumentDtos);
@Autowired
public void setMarketDataService(MarketDataService marketDataService) {
this.marketDataService = marketDataService;
}
}
当调用 toInstrument
方法时,应用程序因 NPE 而失败,试图 marketDataService.findMarketByCode(instrumentDto.getMarketCode())
。
希望这些信息足够了。如果还需要什么,请告诉我。
提前致谢!
更新:
市场数据服务class。它通过@Service注解添加到上下文中。
@Service
public class MarketDataService {
@Autowired
private InstrumentRepository instrumentRepository;
public Instrument findInstrumentByCode(String code) {
return instrumentRepository.findFirstByCode(code);
}
public List<InstrumentDto> getAllInstrumentDtos() {
List<Instrument> instruments = getAllInstruments();
List<InstrumentDto> dtos = Mappers.getMapper(InstrumentMapper.class).fromInstruments(instruments);
return dtos;
}
public void updateInstrument(InstrumentDto instrumentDto) {
Instrument instrument = findInstrumentByCode(instrumentDto.getCode());
if (instrument == null) {
throw new IllegalArgumentException("Market with given code not found!");
}
instrumentRepository.delete(instrument);
instrument = Mappers.getMapper(InstrumentMapper.class).toInstrument(instrumentDto);
instrumentRepository.save(instrument);
}
}
算法如下:@Controller class 获取 PUT 请求并使用请求的主体(instrumentDto 参数)调用 MarketDataService.updateInstrument 方法。后者调用了相同参数的toInstrument方法
你有 NPE 的原因是因为你正在使用 MapStruct Mappers
工厂作为非默认组件模型。
Mappers
工厂不执行任何依赖项注入。
您必须在 MarketDataService
中注入映射器。这样做时要小心,因为你有一个循环依赖。
除此之外,您在 Mapper 中使用的模式并不是真正正确的模式。当简单的 source
就可以时,您正在使用表达式。
例如
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = "spring")
public abstract class InstrumentMapper {
protected InstrumentRepository instrumentRepository;
@Mapping(target = "marketCode", source = "market.code")
public abstract InstrumentDto fromInstrument(Instrument instrument);
public abstract List<InstrumentDto> fromInstruments(List<Instrument> instruments);
@Mapping(target = "market", source = "marketCode")
public abstract Instrument toInstrument(InstrumentDto instrumentDto);
public abstract List<Instrument> toInstruments(List<InstrumentDto> instrumentDtos);
protected Instrument findInstrumentByCode(String code) {
return instrumentRepository.findFirstByCode(code);
}
@Autowired
public void setMarketDataService(MarketDataService marketDataService) {
this.marketDataService = marketDataService;
}
}