【发布时间】:2017-04-12 12:41:36
【问题描述】:
我正在使用 jersey 和 Guice DI,我想使用 Mapstruct 接口
带有@Inject 注释。
那么有什么方法可以强制 Guice 自动装配 Mapstruct 接口实现吗?
【问题讨论】:
标签: java autowired jersey-1.0 mapstruct guice-3
我正在使用 jersey 和 Guice DI,我想使用 Mapstruct 接口
带有@Inject 注释。
那么有什么方法可以强制 Guice 自动装配 Mapstruct 接口实现吗?
【问题讨论】:
标签: java autowired jersey-1.0 mapstruct guice-3
您可以使用@Mapper(componentModel = "jsr330") 将映射器的实现配置为使用JSR 330 注释进行注释。您可以在reference documentation找到更多信息。
然后您可以将 Mapper 接口与模块中的实现类绑定。
绑定它们的一种方法是使用 Guice Linked Bindings:
bind(MyDtoMapper.class).to(MyDtoMapperImpl.class)
绑定它们的另一种方法是使用Instance Bindings:
bind(MyDtoMapper.class).toInstance(MyDtoMapper.INSTANCE)
【讨论】:
componentModel = "jsr330" 真的很方便。它将@javax.inject.Named 和@javax.inject.Singleton 添加到映射器实现中,但是当我尝试使用像@Inject void setBeanMapper(@Named BeanMapper beanMapper) { this.beanMapper = beanMapper; } 这样的setter 注入它时,它试图找到用@com.google.inject.name.Named(value=) 注释的BeanMapper 的实现,但它失败了=(你知道怎么做吗?解决这个问题?
@Inject 和 @Named?也许 guice 不适用于混合注释,也许它们也需要来自 javax.inject。
在使用 Guice 和 jsr330 componentModel 时遇到了问题,尽管我不记得它们到底是什么。我的用例有点复杂,因为我还需要将另一个服务传递给映射器装饰器。也应该适用于您的简单案例。最终在 Guice 模块中执行提供程序方法,如下所示:
public YourModule extends AbstractModule {
//With Decorator
@Provides
@Singleton
FooMapper providesFooMapper(RequiredService requiredSvc) {
FooMapper mapper = Mappers.getMapper(FooMapper.class);
((FooMapperDecorator) mapper).setRequiredService(requiredSvc);
return mapper;
}
//Simple Mapper with no dependencies
@Provides
@Singleton
BarMapper providesBarMapper() {
return Mappers.getMapper(BarMapper.class);
}
}
工作顺利,但我希望 MapStruct 在某些时候能够干净利落地处理这个简单的案例。我还要注意我只使用构造函数注入;除了 YMMV 之外,setter 注入应该同样有效。
【讨论】:
谢谢@Filip。所以是的,@Mapper(componentModel = "jsr330") 几乎让所有工作都起作用了,我必须为我在代码bind(MyDtoMapper.class).toInstance(MyDtoMapper.INSTANCE) 中直接使用的每个映射器创建绑定,并以这种方式在 MyDtoMapper 接口中声明 INSTANCE:MyDtoMapper INSTANCE = Mappers.getMapper( MyDtoMapper.class );
【讨论】:
Mappers 被认为与默认实现一起使用