{"id":1155,"date":"2021-02-06T02:59:21","date_gmt":"2021-02-05T18:59:21","guid":{"rendered":"http:\/\/blog.axqd.net\/?p=1155"},"modified":"2021-02-06T02:59:21","modified_gmt":"2021-02-05T18:59:21","slug":"mapstruct-with-dagger-injection","status":"publish","type":"post","link":"https:\/\/blog.axqd.net\/?p=1155","title":{"rendered":"MapStruct with Dagger Injection"},"content":{"rendered":"\n<p><code>jsr330<\/code>\u7684<code>componentModel<\/code> \u914d\u5408<code>CONSTRUCTOR<\/code>\u7684<code>InjectionStrategy<\/code>\u53ef\u4ee5\u4e0eDagger\u914d\u5408\u4f7f\u7528\u3002<\/p>\n\n\n\n<p>\u5b9a\u4e49Mapper\uff0c\u5e76\u5728map\u7684\u540c\u65f6\u5b8c\u6210\u89e3\u5bc6\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package net.axqd.mapper;\n\nimport org.mapstruct.InjectionStrategy;\nimport org.mapstruct.Mapper;\nimport org.mapstruct.Mapping;\n\n@Mapper(componentModel = \"jsr330\",\n    uses = DecryptorQualifier.class\n    injectionStrategy = InjectionStrategy.CONSTRUCTOR)\npublic interface AToBMapper {\n    @Mapping(\n        source = \"src.encrypted\",\n        target = \"decrypted\",\n        qualifiedByName = { \"DecryptorQualifier\", \"decrypt\" })\n    B mapAToB(final src)\n}<\/code><\/pre>\n\n\n\n<p>\u5176\u4e2d\uff0c<code>DecryptorQualifier<\/code>\u7684\u5b9a\u4e49\u5982\u4e0b\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package net.axqd.mapper;\n\nimport lombok.NonNull;\nimport org.mapstruct.Named;\nimport javax.inject.Inject;\n\n@Named(\"DecryptorQualifier\")\npublic class DecryptorQualifier {\n    private final Service service;\n\n    @Inject\n    public DecryptorQualifier(@NonNull final Service service) {\n        this.service = service;\n    }\n\n    @Named(\"decrypt\")\n    public String decrypt(final String encrypted) {\n        return service.decrypt(encrypted);\n    }\n}<\/code><\/pre>\n\n\n\n<p>\u5b9a\u4e49Mapper\u7684Provider\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package net.axqd.dagger;\n\nimport net.axqd.mapper.AToBMapper;\nimport net.axqd.mapper.AToBMapperImpl;\n\nimport dagger.Module;\nimport dagger.Provides;\nimport javax.inject.Singleton;\n\n@Module\npublic class MapperModule {\n    @Provides\n    @Singleton\n    AToBMapper aToBMapper(final DecryptorQualifier qualifier) {\n        return new AToBMapperImpl(qualifier);\n    }\n}<\/code><\/pre>\n\n\n\n<p>\u5b9a\u4e49Component:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import dagger.Component;\nimport javax.inject.Singleton;\n\n@Component(modules = {\n    MapperModule.class\n})\n@Singleton\npublic interface FooBarComponent {\n    ...\n}<\/code><\/pre>\n\n\n\n<p>\u5355\u5143\u6d4b\u8bd5:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package net.axqd.mapper;\n\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.mockito.InjectMocks;\nimport org.mockito.Mock;\nimport org.mockito.junit.jupiter.MockitoExtension;\n\n@ExtendWith(MockitoExtension.class)\npublic class AToBMapperTest {\n    private static final String ENCRYPTED = \"encrypted\";\n    private static final String DECRYPTED = \"decrypted\";\n\n    @Mock\n    private DecryptorQualifier qualifier;\n\n    @InjectMocks\n    private AToBMapperImpl mapper;\n\n    @Test\n    public void aToBMapper_when_xxx() {\n        when(qualifier.decrypt(ENCRYPTED)).thenReturn(DECRYPTED);\n\n        final A a = A.builder().xxx.build();\n        final B b = mapper.mapAToB(a);\n\n        assertEquals(...);\n    }\n}<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>jsr330\u7684componentModel \u914d\u5408CONSTRUCTOR\u7684InjectionStrategy\u53ef\u4ee5 &hellip; <a href=\"https:\/\/blog.axqd.net\/?p=1155\" class=\"more-link\">\u7ee7\u7eed\u9605\u8bfb<span class=\"screen-reader-text\">\u201cMapStruct with Dagger Injection\u201d<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[212,214,211,213],"class_list":["post-1155","post","type-post","status-publish","format-standard","hentry","category-tech","tag-dagger","tag-dependency-injection","tag-java","tag-mapstruct"],"_links":{"self":[{"href":"https:\/\/blog.axqd.net\/index.php?rest_route=\/wp\/v2\/posts\/1155","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.axqd.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.axqd.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.axqd.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.axqd.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1155"}],"version-history":[{"count":1,"href":"https:\/\/blog.axqd.net\/index.php?rest_route=\/wp\/v2\/posts\/1155\/revisions"}],"predecessor-version":[{"id":1156,"href":"https:\/\/blog.axqd.net\/index.php?rest_route=\/wp\/v2\/posts\/1155\/revisions\/1156"}],"wp:attachment":[{"href":"https:\/\/blog.axqd.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1155"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.axqd.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1155"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.axqd.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1155"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}