具有Spring依赖注入的自定义转换器

时间:2011-07-14 15:35:47

标签: spring dozer

有没有办法在Dozer中定义一个自定义转换器,用于将一个顶级类型转换为另一个顶级类型,它本身就是一个Spring bean,因此可以注入其依赖项?

推土机文档建议添加以下XML定义:

  <converter type="org.dozer.converters.TestCustomConverter" >
    <class-a>org.dozer.vo.CustomDoubleObject</class-a>
    <class-b>java.lang.Double</class-b>
  </converter>

不幸的是,这会导致Dozer直接实例化org.dozer.converters.TestCustomConverter,这会跳过依赖注入。有没有办法引用Spring bean?

6 个答案:

答案 0 :(得分:7)

在CustomConverterWithIds旁边,与上一个答案一样,也可以注入自定义转换器来覆盖映射文件中配置部分中定义的转换器。这样,推土机将使用注入的转换器,而不是使用默认构造函数实例化。

<bean id="dozerMapper" class="org.dozer.DozerBeanMapper" scope="singleton">
    <property name="mappingFiles">
        <list>
            <value><mapping-file-name1></value>
            <value><mapping-file-name2></value>
        </list> 
    </property>
    <property name="customConverters">
        <list>
            <ref bean="entityConverter"/>
        </list>
    </property>
</bean>

<configuration>
   <custom-converters>
     <converter type="my.domain.EntityConverter">
        <class-a>java.lang.Integer</class-a>
        <class-b>my.domain.MyEntity</class-b>
     </converter>
   <custom-converters>
</configuration>

<beans   .... >
   <bean id="entityConverter" class="my.domain.EntityConverter">
        <property ....
   </bean
</beans>

答案 1 :(得分:3)

如果您的自定义转换器是一个spring bean,那么Dozer bean映射器的属性“customConvertersWithIds”可用于引用转换器spring bean。然后使用此id引用映射中的自定义转换器。以下是我让它适合我的方式:

<bean id="dozerMapper" class="org.dozer.DozerBeanMapper" scope="singleton">
        <property name="mappingFiles">
            <list>
                <value><mapping-file-name1></value>
                <value><mapping-file-name2></value>
            </list>
        </property>
        <property name="customConvertersWithId">
            <map>
                <entry key="crbConverter" value-ref="loadableFooBeanConverter"/>
                <entry key="sbConverter" value-ref="loadableXyzBeanConverter"/>
            </map>
        </property>
    </bean>

我注释了转换器类,例如@component(“loadableFooBeanConverter”)

映射示例:

<mapping>
        <class-a>${Abc}</class-a>
        <class-b>${AbcBean}</class-b>
           <field custom-converter-id="sbConverter">
            <a>XyzId</a>
            <b>Xyz</b>
            <b-hint>${XyzBean}</b-hint>
        </field>
</mapping>

答案 2 :(得分:0)

不幸的是,这不受支持。

答案 3 :(得分:0)

要将Spring bean作为自定义转换器注入,我修补了原始的Dozer。您可以查看我的更改并在可以接受的情况下使用它们。更新的来源位于https://bitbucket.org/JRS/open-dozer

您仍需要将自定义转换器记录添加到全局配置中。

答案 4 :(得分:0)

要改进@Chris答案,可以直接引用类以避免声明bean。

在dozer bean声明中声明自定义转换器bean。

<bean id="DozerMapper" class="org.dozer.DozerBeanMapper">
    <property name="mappingFiles">
        <list>
            <value>mapping.xml</value>
        </list>
    </property>
    <property name="customConverters">
        <list>
            <bean class="com.pharmagest.monalisa.rest.service.mapper.MyConverter"/>
        </list>
    </property>
</bean>

在配置中声明映射后(对我来说,在mapping.xml文件中)。

<configuration>
        <stop-on-errors>true</stop-on-errors>
        <date-format>MM/dd/yyyy HH:mm</date-format>
        <wildcard>true</wildcard>
        <custom-converters>
            <converter type="com.pharmagest.monalisa.rest.service.mapper.MyConverter">
                <class-a>com.project.ClassA</class-a>
                <class-b>com.project.ClassB</class-b>
            </converter>
        </custom-converters>
</configuration>

答案 5 :(得分:0)

Spring Boot中针对Gunjan的答案的Java配置如下:

将自定义转换器创建为Bean,如下所示:

@Component
public class LoadableFooBeanConverter extends DozerConverter<BarBean, FooBean> {
    private final Util util; // Any beans that need to be injected into the custom converter

    @Autowired // Constructor Injection
    public LoadableFooBeanConverter(Util util) {
        super(BarBean.class, FooBean.class);
        this.util = util;
    }

    @Override
    public FooBean convertTo(final BarBean source, final FooBean destination) {
        // Your logic
    }

    @Override
    public BarBean convertFrom(final FooBean source, final BarBean destination) {
        // Your logic
    }
}

创建Mapper组件并注册自定义转换器,如下所示:

@Component
@RequiredArgsConstructor // lombok annotation
public class DozerMapper {
    @Autowired
    private final LoadableFooBeanConverter loadableFooBeanConverter;

    @Getter // lombok annotation
    private Mapper mapper;

    @PostConstruct
    public void init() {
        this.mapper = DozerBeanMapperBuilder.create()
                .withMappingBuilders(BarMappingBuilder.builder().build())
                .withCustomConverterWithId("loadableFooBeanConverter", loadableFooBeanConverter)
                .build();
    }

    @Builder // lombok annocation
    private static class BarMappingBuilder extends BeanMappingBuilder {
        @Override
        protected void configure() {
            mapping(FooBar.class, FooBarFoo.class)
                    .fields("fooBean", "barBean", FieldsMappingOptions.customConverterId("loadableFooBeanConverter"));
        }
    }
}