我查看了 Dozer 的常见问题解答和文档,包括 SourceForge 论坛,但我没有看到任何好的教程,甚至没有看到关于如何实现自定义BeanFactory的简单示例。
每个人都说,“只需实现一个 BeanFactory”。你具体是如何实现的?
我用谷歌搜索过,我看到的只是罐子和罐子的来源。
这是我的 BeanFactories 之一,我希望它有助于解释常见的模式:
public class LineBeanFactory implements BeanFactory {
@Override
public Object createBean(final Object source, final Class<?> sourceClass, final String targetBeanId) {
final LineDto dto = (LineDto) source;
return new Line(dto.getCode(), dto.getElectrified(), dto.getName());
}
}
以及对应的 XML 映射:
<mapping>
<class-a bean-factory="com.floyd.nav.web.ws.mapping.dozer.LineBeanFactory">com.floyd.nav.core.model.Line</class-a>
<class-b>com.floyd.nav.web.contract.dto.LineDto</class-b>
</mapping>
这样我声明当需要一个新的 Line 实例时,它应该使用我的 BeanFactory 创建它。这是一个单元测试,可以解释它:
@Test
public void Line_is_created_with_three_arg_constructor_from_LineDto() {
final LineDto dto = createTransientLineDto();
final Line line = (Line) this.lineBeanFactory.createBean(dto, LineDto.class, null);
assertEquals(dto.getCode(), line.getCode());
assertEquals(dto.getElectrified(), line.isElectrified());
assertEquals(dto.getName(), line.getName());
}
所以Object source是映射的源 bean,Class sourceClass是源 bean 的类(我忽略它,因为它总是一个 LineDto 实例)。字符串 targetBeanId是目标 bean 的 ID(太忽略了)。
这是一个实际的实现。显然它没有多大意义,因为 Dozer 会在没有 BeanFactory 的情况下做同样的事情,但是您可以以不同的方式初始化它,而不是仅仅返回一个对象。
public class ComponentBeanFactory implements BeanFactory {
@Override
public Object createBean(Object source, Class<?> sourceClass,
String targetBeanId) {
return new ComponentDto();
}
}
为什么你还需要一个 BeanFactory 呢?也许这将有助于理解您的问题。
自定义 bean 工厂是具有创建 bean 的方法的类。有两种“味道”
a) 静态创建方法
SomeBean x = SomeBeanFactory.createSomeBean();
b) 实例创建方法
SomeBeanFactory sbf = new SomeBeanFactory();
SomeBean x = sbf.createSomeBean();
如果创建和设置 bean 需要一些棘手的逻辑,例如某些属性的初始值取决于外部配置文件,您将创建一个 bean 工厂。bean 工厂类允许您集中有关如何创建如此棘手的 bean 的“知识”。其他类只是调用 create 方法,而不用担心如何正确创建这样的 bean。