在为 mapstruct 制作的抽象 class 中自动装配
Autowiring inside abstract class made for mapstruct
我正在尝试使用 Spring 构建 REST 控制器。为了格式化数据以提高可读性和集成度,我使用了 Mapstruct。这是我写 Mapper 的方式。
@Mapper
public abstract class DeviceDataMapper {
@Autowired
DeviceService deviceService;
public static DeviceDataMapper INSTANCE = Mappers.getMapper(DeviceDataMapper.class);
@Mappings({
@Mapping(source = "deviceId", target = "iddevice"),
@Mapping(source = "deviceName", target = "name")
})
public abstract TODevice deviceToTODevice(DeviceData device);
public DeviceData toDeviceToDeviceData(TODevice toDevice){
DeviceData deviceData = new DeviceData();
deviceData.setDeviceId(toDevice.getIddevice());
deviceData.setDeviceName(toDevice.getName());
deviceData.setDeviceTemplateId(toDevice.getDeviceTemplateId());
try {
deviceData.setDeviceTemplateName(deviceService.findDeviceTemplateById(toDevice.getDeviceTemplateId()).getName());
} catch (Exception e) {
e.printStackTrace();
}
return deviceData;
}}
API 控制器函数如下所示
@RequestMapping(value = "/{deviceId}",method = RequestMethod.GET)
public @ResponseBody DeviceData get(@PathVariable int deviceId) {
DeviceData deviceData=new DeviceData();
try {
deviceData = DeviceDataMapper.INSTANCE.toDeviceToDevice(deviceService.findOne(deviceId));
} catch (Exception e) {
e.printStackTrace();
}
return deviceData;
}
输出设备数据returns 除了一个细节外都很好。我无法使用此功能 deviceService.findDeviceTemplateById(toDevice.getDeviceTemplateId()
(自动连接 deviceService)。错误堆栈跟踪显示 NullPointerException。所以我想知道抽象 class 中是否有关于自动装配资源的可访问性的一般规则?或者是我实例化的方式使这个函数无法访问?我应该改变什么才能让它发挥作用?我也尝试使用 javax.inject
中的 @Inject
得到相同的结果。
为了 @Autowired
工作,DeviceDataMapper
class 需要是一个 Spring bean。自己实例化就不行了
要么将其设为 Spring bean 并像使用它一样使用它,要么将对 deviceService
的引用从您的控制器传递给它。
您可以使用 Spring 作为映射器的组件模型:
@Mapper(componentModel="spring")
public abstract class DeviceDataMapper {
...
}
这样你就可以将依赖项注入它(例如它使用的其他手写)以及将映射器注入其他 类 而不是求助于 INSTANCE
模式。
我正在尝试使用 Spring 构建 REST 控制器。为了格式化数据以提高可读性和集成度,我使用了 Mapstruct。这是我写 Mapper 的方式。
@Mapper
public abstract class DeviceDataMapper {
@Autowired
DeviceService deviceService;
public static DeviceDataMapper INSTANCE = Mappers.getMapper(DeviceDataMapper.class);
@Mappings({
@Mapping(source = "deviceId", target = "iddevice"),
@Mapping(source = "deviceName", target = "name")
})
public abstract TODevice deviceToTODevice(DeviceData device);
public DeviceData toDeviceToDeviceData(TODevice toDevice){
DeviceData deviceData = new DeviceData();
deviceData.setDeviceId(toDevice.getIddevice());
deviceData.setDeviceName(toDevice.getName());
deviceData.setDeviceTemplateId(toDevice.getDeviceTemplateId());
try {
deviceData.setDeviceTemplateName(deviceService.findDeviceTemplateById(toDevice.getDeviceTemplateId()).getName());
} catch (Exception e) {
e.printStackTrace();
}
return deviceData;
}}
API 控制器函数如下所示
@RequestMapping(value = "/{deviceId}",method = RequestMethod.GET)
public @ResponseBody DeviceData get(@PathVariable int deviceId) {
DeviceData deviceData=new DeviceData();
try {
deviceData = DeviceDataMapper.INSTANCE.toDeviceToDevice(deviceService.findOne(deviceId));
} catch (Exception e) {
e.printStackTrace();
}
return deviceData;
}
输出设备数据returns 除了一个细节外都很好。我无法使用此功能 deviceService.findDeviceTemplateById(toDevice.getDeviceTemplateId()
(自动连接 deviceService)。错误堆栈跟踪显示 NullPointerException。所以我想知道抽象 class 中是否有关于自动装配资源的可访问性的一般规则?或者是我实例化的方式使这个函数无法访问?我应该改变什么才能让它发挥作用?我也尝试使用 javax.inject
中的 @Inject
得到相同的结果。
为了 @Autowired
工作,DeviceDataMapper
class 需要是一个 Spring bean。自己实例化就不行了
要么将其设为 Spring bean 并像使用它一样使用它,要么将对 deviceService
的引用从您的控制器传递给它。
您可以使用 Spring 作为映射器的组件模型:
@Mapper(componentModel="spring")
public abstract class DeviceDataMapper {
...
}
这样你就可以将依赖项注入它(例如它使用的其他手写)以及将映射器注入其他 类 而不是求助于 INSTANCE
模式。