Spring Boot训练营:Spring Boot + ModelMapper版
这是Spring Boot训练营系列的Spring Boot + ModelMapper版本。
本次的目標
在Spring Boot应用程序中,使用ModelMapper来执行Bean的复制操作。
在本文中,我们将使用我们自己开发的Starter。
Starter已经在Maven中央仓库中公开,并且任何人都可以使用。
https://github.com/yoshikawaa/modelmapper-spring-boot-starter
这次将使用的库
-
- spring-boot-starter:2.2.0.M4
-
- modelmapper-spring-boot-starter:0.1.0
-
- spring-boot-starter-test:2.2.0.M4
- lombok:1.18.8
ModelMapper是什么
隐藏 Java Bean 的复制过程,提升代码的清晰度。
public Todo convert(TodoForm form) {
Todo todo = new Todo();
todo.setTodoId(form.getTodoId());
todo.setTodoTitle(form.getTodoTitle());
todo.setFinished(form.isFinished());
todo.setCreatedAt(form.getCreatedAt());
return todo;
}
这可以简化为以下形式。
public Todo convert(TodoForm form) {
ModelMapper modelMapper = new ModelMapper();
return modelMapper.map(form, Todo.class);
}
请务必查看这篇文章以获取有关如何使用ModelMapper的详细信息!
对Spring Boot的支持
從這個話題開始,ModelMapper官方沒有提供Spring Boot Starter。
作為相關項目,個人開發的Starter已經宣布了。
然而,对于这个Starter,有一些让我有些担心的地方。
-
- サポートバージョンの古さ
modelmapper:0.7.5
spring-boot-starter:1.2.5.RELEASE
カスタマイズの貧弱さ
Property MappingとConverter以外をカスタマイズする場合、Starterのメリットがない
我尝试做了一下!
所以,我自己制作了一个 Starter 并发布到 Maven Central! 在本文中,我们将使用这个 Starter。
模型映射器-春季启动器
这是用于在Spring Boot中使用ModelMapper的启动器。
通过使用Spring Boot的自动配置机制,可以自动为Spring Boot应用程序定义使用ModelMapper的Bean。开发人员只需在依赖中添加modelmapper-spring-boot-starter即可。
pom.xml 可以被改写成为以下中文形式:
项目配置文件 pom.xml
<dependencies>
<dependency>
<groupId>io.github.yoshikawaa.modelmapper.spring.boot</groupId>
<artifactId>modelmapper-spring-boot-starter</artifactId>
<version>0.1.0</version>
</dependency>
</dependencies>
src/main/java/*/Application.java 的内容进行本地化,只需要一种选项。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
主类未对Spring Boot应用程序的默认设置进行任何更改。
使用ModelMapper的类
在这里我们将使用Controller进行尝试。
除了使用ModelMapper外,我尽量省略了其他元素。
src/main/java/*/web/TodoController.java的中文本地化版。
@Controller
@RequestMapping("todo")
public class TodoController {
// (1)
@Autowired
private ModelMapper modelMapper;
@Autowired
private TodoService todoService;
@PostMapping
public String create(TodoForm form) {
// (2)
Todo todo = modelMapper.map(form, Todo.class);
todoService.create(todo);
// ommitted.
}
}
(1) 由于 ModelMapper 已经自动设置好了,只需要注入即可使用。
(2) 通过ModelMapper的map方法将Bean复制。
自定义映射
在ModelMapper的默认设置中,会自动将源对象和目标对象中名称相同的属性进行复制。
要复制名称不同的属性,需要进行自定义映射。
src/main/java/*/ModelMapperConfig.java 可以进行如下的汉语翻译:
src/main/java/*/ModelMapperConfig.java 文件
@Configuration
public class ModelMapperConfig {
@Bean
TypeMapConfigurer<TodoForm, Todo> typeMap() {
return new TypeMapConfigurer<TodoForm, Todo>() {
@Override
public void configure(TypeMap<TodoForm, Todo> typeMap) {
typeMap.addMapping(TodoForm::getTodoTitle, Todo::setTitle);
}
};
}
}
为了进行自定义映射,定义一个TypeMapConfigurer<源类型, 目标类型>的Bean。
只需定义TypeMapConfigurer Bean,即可自动应用。
注意。
您可以使用@Component而不是@Bean进行定义。
如果使用@Component,则每个自定义映射将对应一个类。
定制映射的验证
建议在定义自定义映射后,验证属性是否完整无遗漏。
src/main/resources/application.yml 的中文本地化翻译
modelmapper:
validate-enabled: true
在ModelMapper的设置中,如果存在属性映射的遗漏,将会触发validate方法并产生错误。
行为的改变
通过定制ModelMapper的复制行为,可以实现更灵活的复制功能。这里,我们将尝试更改复制源属性为空时的行为,不进行复制。
主要资源应用.yml
modelmapper:
skip-null-enabled: true
在 ModelMapper 的设置中,当调用 setSkipNullEnabled 方法时,如果源属性为 null,则不会被复制。
检查ModelMapper的配置
要确认已设置好的ModelMapper配置,只需输出TRACE级别的日志即可。日志输出级别可通过使用Spring Boot的logging属性来进行设置。
主要资源/application.yml
logging:
level:
io.github.yoshikawaa.modelmapper.spring.boot.autoconfigure: trace
JUnit测试用例
在JUnit测试用例中,由于使用的测试用自动配置不同,所以请注意设置的差异。
如果使用@SpringBootTest
加载所有的Bean。
在这种情况下,不需要特别注意使用ModelMapper。
如果您使用@WebMvcTest等功能的话
由于轻量化的需求,仅有限地读取Bean,因此不会加载独立的Auto-Config或@Configuration类等。
在这种情况下,您需要进行ModelMapper的配置。
@ImportAutoConfiguration -> ModelMapperのAuto-Configを読み込みます。
@Import -> カスタムマッピングを読み込みます。
源代码(src)/ 测试 / java / * / web / TodoControllerTest.java
@WebMvcTest
@ImportAutoConfiguration(ModelMapperAutoConfiguration.class) // (1)
@Import(ModelMapperConfig.class) // (2)
class TodoControllerTest {
@Autowired
MockMvc mvc;
@Test
void testCreate() throws Exception {
// execute & assert
mvc.perform(post("/todo").param("todoTitle", "sample"))
.andExpect(status().isOk());
}
(1)通过 @ImportAutoConfiguration 加载 ModelMapperAutoConfiguration 类来进行 ModelMapper 的设置。
(2) 使用@Import来加载自定义映射的@Configuration类。还可以使用数组一次性加载多个类。
注意。
如果您使用@Component创建了自定义映射,可以使用@ComponentScan来代替@Import进行加载,这样就可以了。
总结不需要日本语口译
由于这次没有满意的起动器,所以我们只能适当进行改进,但好在我们也懂得了制作起动器的方法,这很好w。
如果在实际开发中使用ModelMapper,我认为要集中整体行为到哪里,以及如何管理自定义映射可能成为问题,所以使用Starter进行规则化会很好。
请查看我们最新创建的Starter,除了在文章中提到的功能,还支持对ModelMapper进行丰富的定制。如果您要使用,请查阅Starter和ModelMapper的参考资料!