spring boot 常用工具类集成详解groupId
----------------------------------------------------------------------------------------------------------------
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
SnakeYAML 是一个常用的 YAML 解析库,主要用于处理 YAML 格式的配置文件(如 application.yml)。Spring Boot 内部默认集成了 SnakeYAML,用于加载和解析 YAML 配置,将其转换为 Java 对象供应用使用。一、SnakeYAML 在 Spring Boot 中的作用
-
解析 YAML 配置文件:Spring Boot 的核心配置文件(
application.yml或application.yaml)默认通过 SnakeYAML 解析,将配置项绑定到Environment或自定义配置类中。示例application.yml:yamlserver: port: 8080 app: name: my-springboot-app timeout: 3000 -
对象与 YAML 互转:除了配置解析,SnakeYAML 还可用于在业务代码中实现 Java 对象与 YAML 字符串的相互转换(序列化 / 反序列化)。
二、Spring Boot 中使用 SnakeYAML 的两种场景
1. 配置文件解析(自动集成)
spring-boot-starter 间接引入),无需额外配置即可解析 YAML 配置。import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "app") // 绑定前缀为 "app" 的配置
public class AppConfig {
private String name;
private int timeout;
// getter 和 setter
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getTimeout() { return timeout; }
public void setTimeout(int timeout) { this.timeout = timeout; }
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AppController {
@Autowired
private AppConfig appConfig;
@GetMapping("/config")
public String getConfig() {
return "App Name: " + appConfig.getName() + ", Timeout: " + appConfig.getTimeout();
}
}
2. 手动处理 YAML 与对象互转(业务场景)
Spring Boot 已默认包含 SnakeYAML,若需单独引入(非 Spring Boot 项目):
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.33</version> <!-- 版本号可根据需要调整 -->
</dependency>
import org.yaml.snakeyaml.Yaml;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Map;
public class YamlUtils {
// YAML 字符串转 Java 对象(Map)
public static Map<String, Object> yamlToMap(String yamlStr) {
Yaml yaml = new Yaml();
return yaml.load(yamlStr);
}
// Java 对象转 YAML 字符串
public static String objectToYaml(Object obj) {
Yaml yaml = new Yaml();
return yaml.dump(obj);
}
// 从文件读取 YAML 并转换为对象
public static <T> T loadFromFile(String filePath, Class<T> clazz) throws Exception {
Yaml yaml = new Yaml();
try (FileReader reader = new FileReader(filePath)) {
return yaml.loadAs(reader, clazz);
}
}
// 将对象写入 YAML 文件
public static void dumpToFile(Object obj, String filePath) throws Exception {
Yaml yaml = new Yaml();
try (FileWriter writer = new FileWriter(filePath)) {
yaml.dump(obj, writer);
}
}
}
// 1. 对象转 YAML
AppConfig config = new AppConfig();
config.setName("test-app");
config.setTimeout(5000);
String yamlStr = YamlUtils.objectToYaml(config);
System.out.println("YAML:\n" + yamlStr);
// 2. YAML 转对象
AppConfig parsedConfig = YamlUtils.loadFromFile("config.yaml", AppConfig.class);
三、注意事项
-
数据类型匹配:YAML 中的类型(如
null、true/false、数字)需与 Java 类字段类型匹配,否则可能抛出YAMLException。 -
复杂对象处理:对于包含集合、嵌套对象的 YAML,SnakeYAML 会自动解析,但建议使用
TypeDescription或Constructor明确类型,避免类型擦除问题。示例(处理泛型):java运行import org.yaml.snakeyaml.constructor.Constructor; import org.yaml.snakeyaml.nodes.Tag; import org.yaml.snakeyaml.representer.Representer; // 解析包含 List<AppConfig> 的 YAML Representer representer = new Representer(); representer.addClassTag(AppConfig.class, Tag.MAP); // 指定自定义类的标签 Yaml yaml = new Yaml(new Constructor(List.class), representer); List<AppConfig> configs = yaml.load(yamlStr); -
安全问题:SnakeYAML 的默认配置允许解析任意类(可能存在安全风险,如反序列化漏洞)。若处理不可信的 YAML 数据,需限制可解析的类:java运行
// 限制只能解析 AppConfig 类 Constructor constructor = new Constructor(AppConfig.class); Yaml safeYaml = new Yaml(constructor);
总结
----------------------------------------------------------------------------------------------------------------
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-autoconfigure</artifactId>
</dependency>
com.github.xiaoymin 是国产开发者 xiaoymin(肖 ym)在 Maven 仓库中发布开源项目的 Group ID,其最知名的项目是 Knife4j(前身是 swagger-bootstrap-ui)—— 一款基于 Swagger 的增强型 API 文档工具,广泛用于 Spring Boot 项目中生成和展示 API 文档。主要项目:Knife4j
1. 核心功能
- 美化 Swagger 文档界面,支持黑暗模式、接口搜索、在线调试
- 增强接口管理能力(如接口排序、分组、权限控制)
- 支持导出 API 文档为 Markdown、HTML、Word 等格式
- 兼容 Swagger 2.x 和 OpenAPI 3.x 规范
2. 在 Spring Boot 中集成
在
pom.xml 中添加:<!-- Knife4j Spring Boot 2.x 依赖 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version> <!-- 版本号可根据需要更新 -->
</dependency>
创建配置类启用 API 文档:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
@Configuration
public class Knife4jConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(new ApiInfoBuilder()
.title("API 文档")
.description("项目接口文档")
.version("1.0")
.build())
.select()
// 指定扫描的控制器包路径
.apis(RequestHandlerSelectors.basePackage("com.example.controller"))
.paths(PathSelectors.any())
.build();
}
}
启动项目后,通过以下地址访问 Knife4j 文档界面:
http://localhost:8080/doc.html
3. 其他相关项目
com.github.xiaoymin 下还有一些辅助工具:knife4j-extension:Knife4j 扩展模块(如接口签名、加密等)swagger-bootstrap-ui:Knife4j 的早期版本(已停止维护,建议使用 Knife4j)
总结
com.github.xiaoymin 主要关联的是 Knife4j 系列项目,该工具已成为国内 Spring Boot 开发者生成 API 文档的主流选择,相比原生 Swagger UI 更符合中文用户的使用习惯,界面更友好,功能更丰富。----------------------------------------------------------------------------------------------------------------
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
com.google.guava 是 Google 开发的 Java 核心库(Guava)的 Maven 坐标,它提供了大量实用的工具类和增强功能,弥补了 Java 标准库的不足,广泛应用于 Java 项目中。一、Guava 核心价值
- 简化集合操作(提供更强大的集合类型和工具方法)
- 增强字符串处理、缓存、并发编程等能力
- 提供更优雅的异常处理、I/O 操作等工具
- 减少样板代码,提升开发效率
二、主要功能模块与常用类
1. 集合工具(com.google.common.collect)
| 类 / 接口 | 功能说明 |
|---|---|
ImmutableList |
不可变列表(线程安全,创建后不可修改) |
Multimap |
支持一个键映射多个值的集合(类似 Map<K, Collection<V>> 的简化版) |
BiMap |
双向映射(可通过值反向查找键,如 HashBiMap) |
Table |
二维表结构(类似 Map<R, Map<C, V>>,支持行、列双向访问) |
Lists/Sets/Maps |
集合工具类(提供 newArrayList()、transform()、filter() 等便捷方法) |
// 创建不可变列表
List<String> immutableList = ImmutableList.of("a", "b", "c");
// Multimap 示例(一个键对应多个值)
Multimap<String, Integer> multimap = ArrayListMultimap.create();
multimap.put("score", 90);
multimap.put("score", 85);
Collection<Integer> scores = multimap.get("score"); // [90, 85]
// 集合转换
List<Integer> numbers = Lists.newArrayList(1, 2, 3);
List<String> numberStrs = Lists.transform(numbers, n -> "num:" + n); // [num:1, num:2, num:3]
2. 字符串处理(com.google.common.base)
java.lang.String 更丰富的字符串工具:| 类 / 方法 | 功能说明 |
|---|---|
Strings |
字符串工具(isNullOrEmpty()、padStart()、repeat() 等) |
Splitter |
灵活的字符串拆分器(支持按正则、固定长度拆分,忽略空值等) |
Joiner |
字符串拼接器(支持连接集合、处理 null 值) |
CharMatcher |
字符匹配工具(判断字符类型、过滤字符串等) |
// 字符串拼接(自动处理 null)
String joined = Joiner.on(",").skipNulls().join("a", null, "b"); // "a,b"
// 字符串拆分(忽略空字符串)
List<String> parts = Splitter.on(",")
.trimResults()
.omitEmptyStrings()
.splitToList(" a, , b "); // ["a", "b"]
// 字符匹配(保留数字)
String numbers = CharMatcher.digits().retainFrom("abc123def456"); // "123456"
3. 缓存(com.google.common.cache)
ConcurrentHashMap 更强大:| 类 / 接口 | 功能说明 |
|---|---|
Cache/LoadingCache |
缓存接口,支持自动加载、过期策略、最大容量限制 |
CacheBuilder |
缓存构建器(配置过期时间、并发级别、移除监听器等) |
// 构建一个具有过期策略的缓存
LoadingCache<String, String> cache = CacheBuilder.newBuilder()
.maximumSize(100) // 最大缓存项数
.expireAfterWrite(10, TimeUnit.MINUTES) // 写入后10分钟过期
.build(new CacheLoader<String, String>() {
@Override
public String load(String key) throws Exception {
// 缓存未命中时的加载逻辑(如查数据库)
return "value for " + key;
}
});
// 使用缓存
String value = cache.get("key1"); // 首次加载,后续直接从缓存获取
4. 并发编程(com.google.common.util.concurrent)
| 类 / 接口 | 功能说明 |
|---|---|
ListenableFuture |
可监听的 Future(支持注册回调,避免阻塞等待) |
Futures |
异步任务工具类(处理 ListenableFuture 链、合并结果等) |
RateLimiter |
限流器(控制接口调用频率,如每秒最多 100 次请求) |
// 限流器(每秒允许5个请求)
RateLimiter limiter = RateLimiter.create(5.0);
// 尝试获取令牌,未获取到则等待
limiter.acquire(); // 阻塞直到获取令牌
doSomething(); // 执行受限制的操作
5. 其他实用工具
- I/O 操作:
com.google.common.io提供Files、Resources等工具,简化文件读写、资源加载。 - 数学工具:
com.google.common.math提供IntMath、LongMath等,支持溢出检查、最大公约数计算。 - 前置条件检查:
com.google.common.base.Preconditions提供checkNotNull()、checkArgument()等,简化参数校验。
// 参数校验
Preconditions.checkNotNull(user, "用户不能为空");
Preconditions.checkArgument(age > 0, "年龄必须为正数");
// 文件操作
File file = new File("test.txt");
String content = Files.asCharSource(file, Charsets.UTF_8).read(); // 读取文件内容
三、在项目中引入 Guava
Maven 依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version> <!-- 版本号可根据需要更新 -->
</dependency>
- 版本说明:
-jre后缀版本依赖 Java 8+ 标准库,-android版本适用于 Android 环境。
四、使用注意事项
- 版本兼容性:Guava 部分版本(如 21.0+)要求 Java 8+,需根据项目 JDK 版本选择合适版本。
- 避免过度依赖:优先使用 JDK 自带功能(如 Java 8 的
Stream可替代部分 Guava 集合工具)。 - 了解实现细节:例如
ImmutableList是不可变的,避免在需要修改的场景中使用。
总结
----------------------------------------------------------------------------------------------------------------
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</dependency>
org.mapstruct 是 MapStruct 框架的 Maven 坐标,MapStruct 是一个类型安全的 Java Bean 映射工具,通过注解处理器在编译时生成映射代码,解决了手动编写对象转换逻辑(如 DO 与 DTO 互转)的繁琐问题。一、MapStruct 核心优势
- 类型安全:编译时检查属性映射是否匹配,避免运行时类型转换错误。
- 高性能:生成的代码是直接调用
getter/setter的普通 Java 代码,比反射(如BeanUtils)效率更高。 - 可维护性:映射规则集中在注解中,无需手动编写转换工具类。
- 灵活性:支持复杂映射场景(如嵌套对象、集合转换、自定义转换逻辑)。
二、核心依赖与配置
<!-- 核心依赖 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.5.Final</version> <!-- 稳定版本,可按需更新 -->
</dependency>
<!-- 注解处理器(编译时生成代码) -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version>
<scope>provided</scope> <!-- 仅编译时需要 -->
</dependency>
三、核心注解与使用示例
@Mapper、@Mapping 等。1. 基础对象映射
User(数据实体)转换为 UserDTO(数据传输对象)。// 数据实体
public class User {
private Long id;
private String userName;
private LocalDate birthDate;
// getter/setter
}
// DTO
public class UserDTO {
private Long userId;
private String name;
private String birthDate; // 日期以字符串形式展示
// getter/setter
}
// 映射器接口(MapStruct 会生成实现类)
@Mapper(componentModel = "spring") // 生成 Spring 管理的 Bean
public interface UserMapper {
// 单例实例(MapStruct 自动生成)
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
// 自定义映射规则
@Mapping(source = "id", target = "userId") // 字段名不同
@Mapping(source = "userName", target = "name") // 字段名不同
@Mapping(source = "birthDate", target = "birthDate", dateFormat = "yyyy-MM-dd") // 日期格式化
UserDTO toDTO(User user);
// 反向映射(DTO 转实体)
@Mapping(source = "userId", target = "id")
@Mapping(source = "name", target = "userName")
@Mapping(source = "birthDate", target = "birthDate", dateFormat = "yyyy-MM-dd")
User toEntity(UserDTO dto);
}
// 转换实体为 DTO
User user = new User(1L, "张三", LocalDate.of(1990, 1, 1));
UserDTO dto = UserMapper.INSTANCE.toDTO(user);
// dto 结果:userId=1, name="张三", birthDate="1990-01-01"
2. 集合映射
List、Set 等集合类型的自动转换,只需定义单个对象的映射方法,集合映射会自动生成。@Mapper(componentModel = "spring")
public interface UserMapper {
// 单个对象映射(集合映射依赖此方法)
UserDTO toDTO(User user);
// 集合映射(MapStruct 自动生成循环调用 toDTO 的代码)
List<UserDTO> toDTOList(List<User> users);
}
3. 自定义转换逻辑
qualifiedByName 引用自定义方法。@Mapper(componentModel = "spring")
public interface OrderMapper {
@Mapping(source = "status", target = "statusDesc", qualifiedByName = "orderStatusConverter")
OrderDTO toDTO(Order order);
// 自定义转换方法(通过 @Named 标记)
@Named("orderStatusConverter")
default String convertStatus(Integer status) {
if (status == 0) return "未支付";
if (status == 1) return "已支付";
return "未知状态";
}
}
四、生成代码的特点
- 代码透明:可在
target/generated-sources/annotations目录查看生成的代码。 - 无反射:直接调用
getter/setter,性能接近手写代码。 - 空值安全:默认处理
null值(不会因源对象为null抛出异常)。
五、与其他映射工具的对比
| 工具 | 实现方式 | 性能 | 类型安全 | 灵活性 |
|---|---|---|---|---|
| MapStruct | 编译时生成代码 | 极高 | 编译时检查 | 支持复杂映射 |
| Apache BeanUtils | 反射 | 低 | 运行时检查 | 简单映射 |
| ModelMapper | 反射 + 智能匹配 | 中 | 运行时检查 | 自动推断映射 |
总结
org.mapstruct 对应的 MapStruct 框架是 Java 项目中对象转换的最佳实践之一,通过编译时代码生成实现了类型安全、高性能的映射逻辑,大幅减少了手动编写转换代码的工作量。其核心注解 @Mapper 和 @Mapping 提供了灵活的映射规则配置,支持从简单字段映射到复杂自定义转换的全场景需求。----------------------------------------------------------------------------------------------------------------
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-json</artifactId>
</dependency>
cn.hutool 是国产 Java 工具库 Hutool 的 Maven 坐标,它是一个功能全面、开箱即用的工具类集合,旨在简化 Java 开发中的常见操作,减少重复代码。Hutool 涵盖了字符串处理、日期时间、集合操作、IO 流、加密解密等近百个工具类,被广泛应用于国内 Java 项目中。一、Hutool 的核心优势
- 功能全面:覆盖开发中 80% 以上的工具类需求,避免引入多个零散库。
- 零依赖:纯 Java 实现,不依赖其他第三方库,体积小巧(约 1.5MB)。
- 易用性强:API 设计简洁直观,方法命名符合中文开发者习惯。
- 兼容性好:支持 JDK 8+,适配主流框架(Spring Boot、MyBatis 等)。
二、主要功能模块与常用工具类
1. 核心工具类(cn.hutool.core)
| 工具类 | 功能说明 |
|---|---|
StrUtil |
字符串工具(判空、拼接、截取、替换等,替代 StringUtils) |
CollectionUtil |
集合工具(创建集合、判断空、合并、过滤等) |
ObjectUtil |
对象工具(判空、克隆、比较等) |
NumberUtil |
数字工具(加减乘除、四舍五入、数字转换等) |
// 字符串判空(比 StringUtils 更直观)
StrUtil.isEmpty(""); // true
StrUtil.isNotEmpty("hutool"); // true
// 字符串拼接
String str = StrUtil.format("Hello, {}!", "Hutool"); // "Hello, Hutool!"
// 集合操作
List<String> list = CollectionUtil.newArrayList("a", "b");
CollectionUtil.addIfAbsent(list, "c"); // 仅添加不存在的元素
2. 日期时间工具(cn.hutool.core.date)
LocalDateTime 及传统 Date。| 工具类 / 常量 | 功能说明 |
|---|---|
DateUtil |
日期工具(解析、格式化、加减、比较等) |
LocalDateTimeUtil |
JDK 8+ 日期工具(处理 LocalDateTime) |
DatePattern |
常用日期格式常量(如 yyyy-MM-dd HH:mm:ss) |
// 解析字符串为日期
Date date = DateUtil.parse("2023-01-01", "yyyy-MM-dd");
// 计算两个日期差(天)
long days = DateUtil.between(DateUtil.parse("2023-01-01"), DateUtil.parse("2023-01-10"), DateUnit.DAY); // 9
// LocalDateTime 操作
LocalDateTime now = LocalDateTimeUtil.now();
LocalDateTime tomorrow = LocalDateTimeUtil.plusDays(now, 1); // 加1天
3. IO 工具(cn.hutool.core.io)
| 工具类 | 功能说明 |
|---|---|
FileUtil |
文件工具(创建文件、复制、移动、删除、读取内容等) |
IoUtil |
流工具(读取流内容、复制流、关闭流等) |
ResourceUtil |
资源工具(读取 classpath 下的资源文件) |
// 读取文件内容(自动处理编码和流关闭)
String content = FileUtil.readString("test.txt", CharsetUtil.UTF_8);
// 写入文件
FileUtil.writeString("Hello Hutool", "output.txt", CharsetUtil.UTF_8);
// 读取 classpath 资源
String config = ResourceUtil.readUtf8Str("config.properties");
4. 加密解密(cn.hutool.crypto)
| 工具类 | 功能说明 |
|---|---|
SecureUtil |
加密工具入口(简化 MD5、SHA、AES 等调用) |
SymmetricCrypto |
对称加密(AES、DES 等) |
AsymmetricCrypto |
非对称加密(RSA、DSA 等) |
// MD5 加密
String md5 = SecureUtil.md5("123456"); // 输出 123456 的 MD5 哈希值
// AES 加密解密
SymmetricCrypto aes = SecureUtil.aes("myKey1234567890".getBytes()); // 密钥长度 16/24/32 字节
String encrypt = aes.encryptBase64("secret"); // 加密
String decrypt = aes.decryptStr(encrypt); // 解密,结果为 "secret"
5. 其他实用模块
-
HTTP 客户端(
cn.hutool.http):HttpUtil简化 HTTP 请求(GET/POST、文件上传等),无需依赖 OkHttp 或 HttpClient。java运行// 发送 GET 请求 String result = HttpUtil.get("https://www.baidu.com"); -
JSON 处理(
cn.hutool.json):JSONUtil支持 JSON 字符串与对象互转,兼容 FastJSON 语法。java运行// JSON 字符串转对象 User user = JSONUtil.toBean("{\"name\":\"张三\"}", User.class); -
验证码生成(
cn.hutool.captcha):LineCaptcha、CircleCaptcha快速生成图形验证码。java运行// 生成 100x50 的验证码 LineCaptcha captcha = CaptchaUtil.createLineCaptcha(100, 50); captcha.write("captcha.png"); // 写入文件 String code = captcha.getCode(); // 验证码文本
三、在项目中引入 Hutool
Maven 依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version> <!-- 最新稳定版,可按需更新 -->
</dependency>
hutool-all包含所有模块,若需按需引入(如仅用 IO 工具),可单独引入子模块(如hutool-core、hutool-io)。
四、使用建议
- 按需学习:无需记忆所有工具类,用时查阅 官方文档 即可。
- 避免过度封装:Hutool 已足够简洁,无需再二次封装工具类。
- 版本选择:优先使用最新稳定版,修复了旧版本的 Bug 并增强了功能。
总结
cn.hutool 对应的 Hutool 是国产 Java 工具库的优秀代表,其设计理念贴合国内开发者习惯,功能覆盖全面,极大简化了日常开发中的重复工作。无论是字符串处理、日期操作,还是加密解密、HTTP 请求,Hutool 都能提供简洁高效的解决方案,是 Java 项目的 “必备工具库” 之一。----------------------------------------------------------------------------------------------------------------
<dependency>
<groupId>com.github.dozermapper</groupId>
<artifactId>dozer-core</artifactId>
</dependency>
com.github.dozermapper 是 Dozer 框架的 Maven 坐标,Dozer 是一个经典的 Java Bean 映射工具,用于实现不同对象之间的属性转换(如 DO 与 DTO、VO 之间的映射)。它通过 XML 配置或注解定义映射规则,自动处理字段名匹配、类型转换等逻辑,曾广泛应用于 Java 项目中。一、Dozer 的核心特点
- 自动映射:默认按字段名匹配(忽略大小写),无需手动编写
getter/setter转换代码。 - 灵活配置:支持 XML 配置文件、注解、API 三种方式定义映射规则,应对复杂场景。
- 类型转换:内置常用类型转换器(如
String与Date、Long与String等),也支持自定义转换器。 - 嵌套对象映射:自动处理嵌套对象的属性转换(如
User.addr.city映射到UserDTO.address.cityName)。
二、核心依赖与配置
Maven 依赖
<dependency>
<groupId>com.github.dozermapper</groupId>
<artifactId>dozer-core</artifactId>
<version>6.5.0</version> <!-- 最新稳定版,需注意兼容性 -->
</dependency>
- 注意:Dozer 自 2020 年后更新缓慢,部分新特性(如 Java 8+ 类型支持)需谨慎使用。
三、基本使用方式
1. 基础映射(默认按字段名匹配)
User 转换为 UserDTO,字段名一致时自动映射。// 源对象
public class User {
private Long id;
private String userName;
private Date birthDate;
// getter/setter
}
// 目标对象
public class UserDTO {
private Long id; // 与源字段名一致
private String userName; // 与源字段名一致
private String birthDate; // 类型不同(Date → String)
// getter/setter
}
// 映射工具类(单例模式)
public class DozerMapperUtil {
private static final Mapper mapper = DozerBeanMapperBuilder.buildDefault();
public static <T> T map(Object source, Class<T> targetClass) {
if (source == null) {
return null;
}
return mapper.map(source, targetClass);
}
}
// 使用示例
User user = new User(1L, "张三", new Date());
UserDTO dto = DozerMapperUtil.map(user, UserDTO.class);
2. 自定义映射规则(XML 配置)
src/main/resources/dozer/ 目录)。user-mapping.xml<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://dozer.sourceforge.net
http://dozer.sourceforge.net/schema/beanmapping.xsd">
<!-- User 与 UserDTO 的映射规则 -->
<mapping>
<class-a>com.example.User</class-a>
<class-b>com.example.UserDTO</class-b>
<!-- 字段名不同时映射 -->
<field>
<a>userName</a> <!-- 源字段 -->
<b>name</b> <!-- 目标字段 -->
</field>
<!-- 日期类型转换(指定格式) -->
<field>
<a>birthDate</a>
<b>birthDate</b>
<a-hint>java.util.Date</a-hint>
<b-hint>java.lang.String</b-hint>
<field-exclude>false</field-exclude>
<format>yyyy-MM-dd</format> <!-- 日期格式化 -->
</field>
</mapping>
</mappings>
// 自定义映射器(加载 XML 配置)
public class CustomDozerMapper {
private static final Mapper mapper;
static {
List<String> mappingFiles = new ArrayList<>();
mappingFiles.add("dozer/user-mapping.xml"); // 加载自定义配置
mapper = DozerBeanMapperBuilder.create()
.withMappingFiles(mappingFiles)
.build();
}
public static <T> T map(Object source, Class<T> targetClass) {
return mapper.map(source, targetClass);
}
}
3. 注解方式配置(简化 XML)
@Mapping 直接在类上定义映射规则:import org.dozer.Mapping;
public class UserDTO {
@Mapping("id") // 对应源对象的 id 字段
private Long userId;
@Mapping("userName") // 对应源对象的 userName 字段
private String name;
@Mapping(value = "birthDate", dateFormat = "yyyy-MM-dd") // 日期格式化
private String birthDate;
// getter/setter
}
四、与 MapStruct 的对比
| 特性 | Dozer | MapStruct |
|---|---|---|
| 实现方式 | 运行时通过反射实现 | 编译时生成 Java 代码 |
| 性能 | 较低(反射开销) | 极高(直接调用 getter/setter) |
| 类型安全 | 运行时检查(易出错) | 编译时检查(更可靠) |
| 灵活性 | 配置复杂(依赖 XML) | 注解驱动(更简洁) |
| 维护状态 | 更新缓慢(几乎停滞) | 活跃更新(支持新特性) |
五、使用建议
- 新项目谨慎选择:Dozer 已进入维护模式,功能更新停滞,且性能不如 MapStruct,新项目建议优先使用 MapStruct。
- 老项目迁移:若已有项目使用 Dozer,可逐步迁移到 MapStruct(二者 API 风格相似,迁移成本较低)。
- 特殊场景:若需动态映射(运行时动态修改映射规则),Dozer 的反射机制可能更适合(但需权衡性能)。
总结
com.github.dozermapper 对应的 Dozer 是一款经典的对象映射工具,通过 XML 或注解实现属性转换,曾广泛用于 Java 项目。但由于其基于反射的实现导致性能较差,且维护活跃度低,目前已逐渐被编译时生成代码的 MapStruct 取代。对于新项目,建议优先选择 MapStruct;对于老项目,可根据性能需求决定是否迁移。----------------------------------------------------------------------------------------------------------------
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
org.projectlombok 是 Lombok 库的 Maven 坐标,Lombok 是一款 Java 开发工具,通过注解简化 Java 类的代码编写,自动生成 getter/setter、构造方法、toString 等样板代码,显著减少代码冗余。一、Lombok 核心价值
- 消除样板代码:自动生成常用方法(如
getter/setter、toString()、equals()等),减少手动编写。 - 提升开发效率:修改字段时无需同步修改相关方法,降低维护成本。
- 代码更简洁:聚焦业务逻辑,类结构更清晰。
二、核心依赖与安装
1. Maven 依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version> <!-- 最新稳定版,兼容 JDK 8+ -->
<scope>provided</scope> <!-- 仅编译时需要,运行时不依赖 -->
</dependency>
2. IDE 插件安装
- IntelliJ IDEA:
File → Settings → Plugins,搜索Lombok安装并重启。 - Eclipse:通过 Eclipse Marketplace 搜索
Lombok安装,或手动执行 Lombok Jar 包的安装程序。
三、常用注解详解
1. @Data(最常用)
- 作用:组合注解,自动生成
getter、setter、toString()、equals()、hashCode()方法。 - 适用场景:普通 Java Bean(如 DTO、VO)。
import lombok.Data;
@Data
public class User {
private Long id;
private String name;
private Integer age;
// 无需手动编写 getter/setter 等方法
}
2. @Getter / @Setter
- 作用:为类或字段生成
getter/setter方法。 - 灵活使用:可标注在类上(所有字段生效)或单个字段上(仅该字段生效)。
import lombok.Getter;
import lombok.Setter;
public class User {
@Getter @Setter private Long id; // 仅为 id 生成 get/set
private String name; // 无 get/set
}
3. @NoArgsConstructor / @AllArgsConstructor / @RequiredArgsConstructor
- 作用:生成构造方法:
@NoArgsConstructor:无参构造方法。@AllArgsConstructor:全参构造方法(包含所有字段)。@RequiredArgsConstructor:必需参数构造方法(仅包含被@NonNull标注或final修饰的字段)。
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
@NoArgsConstructor // 无参构造
@AllArgsConstructor // 全参构造
@RequiredArgsConstructor // 必需参数构造
public class User {
private final Long id; // final 字段,属于必需参数
@NonNull private String name; // @NonNull 标注,属于必需参数
private Integer age; // 普通字段,非必需
}
4. @ToString
- 作用:生成
toString()方法,默认包含所有字段。 - 常用属性:
exclude:排除指定字段(如@ToString(exclude = "password"))。of:仅包含指定字段(如@ToString(of = {"id", "name"}))。
import lombok.ToString;
@ToString(exclude = "password") // toString 中不包含 password
public class User {
private Long id;
private String name;
private String password;
}
5. @EqualsAndHashCode
- 作用:生成
equals()和hashCode()方法,默认基于所有非静态字段。 - 常用属性:
exclude(排除字段)、of(包含字段),用法同@ToString。
6. @Slf4j / @Log
- 作用:自动生成日志对象(如
private static final Logger log = LoggerFactory.getLogger(XXX.class);)。 - 适用场景:需要日志输出的类(Service、Controller 等)。
import lombok.extern.slf4j.Slf4j;
@Slf4j // 生成 log 日志对象(基于 SLF4J)
@RestController
public class UserController {
public void getuser() {
log.info("查询用户信息"); // 直接使用 log 对象
}
}
7. @Builder
- 作用:生成建造者模式代码,支持链式调用创建对象。
- 适用场景:字段较多的类,创建对象时更简洁。
import lombok.Builder;
import lombok.Data;
@Data
@Builder // 生成建造者模式
public class User {
private Long id;
private String name;
private Integer age;
}
// 使用示例
User user = User.builder()
.id(1L)
.name("张三")
.age(20)
.build();
8. @NonNull
- 作用:标记字段或方法参数不可为
null,生成 null 校验代码。 - 效果:若传入
null,会抛出NullPointerException。
import lombok.NonNull;
public class User {
private String name;
public void setName(@NonNull String name) { // 参数不可为 null
this.name = name;
}
}
四、工作原理
getter、构造方法等),并将生成的代码合并到字节码中。因此:- 运行时无需依赖 Lombok 库(
scope=provided)。 - 反编译 class 文件可看到生成的完整代码。
五、注意事项
- 调试问题:直接调试时可能无法查看自动生成的方法,需通过反编译 class 文件确认。
- 继承场景:
@Data生成的equals()/hashCode()不会考虑父类字段,需结合@EqualsAndHashCode(callSuper = true)使用。 - 与 IDE 配合:必须安装 Lombok 插件,否则 IDE 会提示 “方法不存在”(不影响编译)。
- 代码可读性:过度使用可能导致团队新成员理解成本增加,建议团队统一规范。
总结
org.projectlombok 对应的 Lombok 是 Java 开发的 “减负工具”,通过注解自动生成样板代码,大幅提升开发效率。其核心注解 @Data、@Getter、@Setter、@Slf4j 等已成为主流项目的标配,但需注意与 IDE 配合及团队规范,平衡代码简洁性与可读性。----------------------------------------------------------------------------------------------------------------
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</dependency>
org.apache.poi 是 Apache 软件基金会旗下 POI 项目的 Maven 坐标,POI(Poor Obfuscation Implementation)是 Java 领域处理 Microsoft Office 文档的核心库,支持读写 Excel、Word、PowerPoint 等格式文件,尤其在 Excel 处理方面应用广泛。一、POI 核心功能
- Excel:
.xls(BIFF8 格式,Excel 97-2003)和.xlsx(OOXML 格式,Excel 2007+)。 - Word:
.doc和.docx格式(主要通过 HWPF 和 XWPF 模块)。 - PowerPoint:
.ppt和.pptx格式(主要通过 HSLF 和 XSLF 模块)。
二、核心模块与依赖
| 模块 | 功能说明 | Maven 依赖坐标 |
|---|---|---|
poi |
处理 .xls 格式(Excel 97-2003) |
<artifactId>poi</artifactId> |
poi-ooxml |
处理 .xlsx 格式(Excel 2007+) |
<artifactId>poi-ooxml</artifactId> |
poi-ooxml-schemas |
OOXML 格式的 XML Schema 定义(依赖) | <artifactId>poi-ooxml-schemas</artifactId> |
poi-scratchpad |
处理 Word(.doc)、PowerPoint(.ppt)等 | <artifactId>poi-scratchpad</artifactId> |
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.4</version> <!-- 最新稳定版,兼容 Java 8+ -->
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.4</version>
</dependency>
三、Excel 处理核心类与示例
1. 处理 .xlsx 格式(Excel 2007+)
XSSF 相关类(XSSFWorkbook、XSSFSheet 等):import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFCell;
import java.io.FileOutputStream;
import java.io.IOException;
public class ExcelWriter {
public static void main(String[] args) {
// 创建工作簿(Workbook)
try (XSSFWorkbook workbook = new XSSFWorkbook()) {
// 创建工作表(Sheet)
XSSFSheet sheet = workbook.createSheet("用户列表");
// 创建表头行(Row)
XSSFRow headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue("ID");
headerRow.createCell(1).setCellValue("姓名");
headerRow.createCell(2).setCellValue("年龄");
// 写入数据行
Object[][] data = {{1, "张三", 20}, {2, "李四", 25}};
for (int i = 0; i < data.length; i++) {
XSSFRow row = sheet.createRow(i + 1); // 从第1行开始(0是表头)
row.createCell(0).setCellValue((Integer) data[i][0]);
row.createCell(1).setCellValue((String) data[i][1]);
row.createCell(2).setCellValue((Integer) data[i][2]);
}
// 调整列宽(自适应内容)
sheet.autoSizeColumn(0);
sheet.
