【问题标题】:How can i combine Guice and Mapstruct?如何结合 Guice 和 Mapstruct?
【发布时间】:2017-04-12 12:41:36
【问题描述】:

我正在使用 jersey 和 Guice DI,我想使用 Mapstruct 接口 带有@Inject 注释。 那么有什么方法可以强制 Guice 自动装配 Mapstruct 接口实现吗?

【问题讨论】:

    标签: java autowired jersey-1.0 mapstruct guice-3


    【解决方案1】:

    您可以使用@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)
    

    【讨论】:

    • 感谢@filip 的快速响应! 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 的实现,但它失败了=(你知道怎么做吗?解决这个问题?
    • 我对 guice 没有太多经验,也许我们需要添加一个使用 guice 设置的示例。您在 setter 中使用了哪个 @Inject@Named?也许 guice 不适用于混合注释,也许它们也需要来自 javax.inject
    • 嗨,你能检查一下stackoverflow.com/questions/64770274/…我试过但不能正确注射
    【解决方案2】:

    在使用 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 注入应该同样有效。

    【讨论】:

    • 在 MapStruct 中支持构造函数和/或字段注入已经存在一个未解决的问题。如果您想跟踪状态,请关注this 问题。
    【解决方案3】:

    谢谢@Filip。所以是的,@Mapper(componentModel = "jsr330") 几乎让所有工作都起作用了,我必须为我在代码bind(MyDtoMapper.class).toInstance(MyDtoMapper.INSTANCE) 中直接使用的每个映射器创建绑定,并以这种方式在 MyDtoMapper 接口中声明 INSTANCE:MyDtoMapper INSTANCE = Mappers.getMapper( MyDtoMapper.class );

    【讨论】:

    • 我用你的例子和 Guice 的链接绑定更新了我的答案。我更喜欢使用它,因为 MapStruct 中的 Mappers 被认为与默认实现一起使用
    猜你喜欢
    • 1970-01-01
    • 2021-02-22
    • 1970-01-01
    • 2013-11-21
    • 2011-06-19
    • 2018-01-30
    • 1970-01-01
    • 2019-10-12
    • 2018-03-30
    相关资源
    最近更新 更多