EasyCode进阶玩法:自定义Lombok+Swagger代码模板(IDEA2023实测)
EasyCode进阶玩法自定义LombokSwagger代码模板IDEA2023实测在团队协作开发中实体类与接口文档的同步维护常常成为效率瓶颈。传统开发模式下我们需要手动编写大量重复的Getter/Setter方法同时为每个API接口添加Swagger注解这不仅耗时耗力还容易因疏忽导致文档与代码不一致。本文将带你深入IntelliJ IDEA的EasyCode插件高级用法通过自定义模板实现Lombok注解与Swagger文档的自动化生成让代码更简洁、文档更规范。1. 环境准备与插件配置1.1 基础环境搭建确保你的开发环境满足以下条件IntelliJ IDEA 2023.xUltimate或Community版均可JDK 1.8Maven 3.6已安装EasyCode插件Marketplace搜索安装提示建议在插件市场安装最新版EasyCode老版本可能缺少某些模板语法支持1.2 必要依赖配置在项目的pom.xml中添加Lombok和Swagger依赖dependencies !-- Lombok自动生成代码 -- dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId version1.18.24/version scopeprovided/scope /dependency !-- Swagger API文档 -- dependency groupIdio.springfox/groupId artifactIdspringfox-swagger2/artifactId version3.0.0/version /dependency !-- Swagger UI界面 -- dependency groupIdio.springfox/groupId artifactIdspringfox-swagger-ui/artifactId version3.0.0/version /dependency /dependencies2. 改造实体类模板2.1 原始模板分析默认的实体类模板会生成包含所有字段的Getter/Setter方法以及toString()实现。对于包含20字段的大型实体类这些代码会显著增加文件体积降低可读性。2.2 集成Lombok注解修改EasyCode的entity.java模板路径Settings → Other Settings → EasyCode → Template Setting## 引入宏定义 $!define ## 设置包路径 #setPackageSuffix(entity) ## 自动导入 $!autoImport import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; import java.io.Serializable; ## 类注释 #tableComment(实体类) Data Accessors(chain true) ApiModel($!{tableInfo.comment}) public class $!{tableInfo.name} implements Serializable { private static final long serialVersionUID $!tool.serial(); #foreach($column in $tableInfo.fullColumn) ApiModelProperty(${column.comment}) private $!{tool.getClsNameByFullName($column.type)} $!{column.name}; #end }关键改进点用Data替代手动Getter/SetterAccessors(chain true)支持链式调用ApiModel和ApiModelProperty自动添加Swagger文档注解2.3 版本兼容处理针对不同Lombok版本可能需要调整模板功能需求旧版本(1.16.x)解决方案新版本(1.18)推荐方案链式调用Setter Accessors组合单用Accessors构造方法显式AllArgsConstructorRequiredArgsConstructorBuilder模式需完整注解Builder单注解即可3. 接口层模板优化3.1 Controller模板改造原始的Controller模板通常缺少API文档说明改造后的controller.java模板## 设置回调 $!callback.setFileName($tool.append($tableInfo.name, Controller.java)) $!callback.setSavePath($tool.append($tableInfo.savePath, /controller)) ## 定义包路径 #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}controller; import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name}; import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; RestController RequestMapping(/api/$!tool.firstLowerCase($tableInfo.name)) Api(tags $!{tableInfo.comment}管理) public class $!{tableInfo.name}Controller { Autowired private $!{tableInfo.name}Service $!tool.firstLowerCase($tableInfo.name)Service; GetMapping(/{id}) ApiOperation(根据ID查询$!{tableInfo.comment}) public $!{tableInfo.name} getById(PathVariable $!pk.shortType id) { return $!{tool.firstLowerCase($tableInfo.name)}Service.queryById(id); } PostMapping ApiOperation(新增$!{tableInfo.comment}) public Boolean save(RequestBody $!{tableInfo.name} $!tool.firstLowerCase($tableInfo.name)) { return $!{tool.firstLowerCase($tableInfo.name)}Service.insert($!tool.firstLowerCase($tableInfo.name)); } ## 其他方法类似添加ApiOperation注解... }3.2 响应体统一封装为保持API响应格式统一建议创建基础响应类Data ApiModel(基础响应体) public class ResultT { ApiModelProperty(状态码) private Integer code; ApiModelProperty(响应消息) private String message; ApiModelProperty(响应数据) private T data; public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMessage(success); result.setData(data); return result; } }然后在Controller模板中统一使用GetMapping(/{id}) ApiOperation(根据ID查询$!{tableInfo.comment}) public Result$!{tableInfo.name} getById(PathVariable $!pk.shortType id) { return Result.success($!{tool.firstLowerCase($tableInfo.name)}Service.queryById(id)); }4. 高级模板技巧4.1 条件生成策略通过Velocity条件判断实现灵活生成## 根据表名前缀决定生成策略 #if($tableInfo.name.startsWith(Sys)) ## 系统表特殊处理 RequiresRoles(admin) #elseif($tableInfo.name.startsWith(Biz)) ## 业务表处理 ApiOperation(业务操作$!{tableInfo.comment}) #end4.2 字段级自定义针对特定字段添加特殊注解#foreach($column in $tableInfo.fullColumn) #if($column.name.contains(email)) Email #end #if($column.type.equals(java.lang.String) $column.obj.size() 255) Size(max $column.obj.size()) #end private $!{tool.getClsNameByFullName($column.type)} $!{column.name}; #end4.3 多模板切换方案对于大型项目可以创建不同场景的模板组basic-template基础CRUD模板dto-template包含DTO转换的模板cache-template集成Redis缓存的模板通过修改settings.zip文件实现模板组的导入导出# 导出当前模板配置 zip -r my-templates.zip ~/.IntelliJIdea*/config/options/EasyCode*.xml # 导入团队统一模板 unzip team-templates.zip -d ~/.IntelliJIdea*/config/options/5. 团队协作最佳实践5.1 模板版本管理将模板文件纳入Git管理建议目录结构team-templates/ ├── entity.vm ├── controller.vm ├── service.vm └── README.md在README中记录模板变更日志版本变更内容适用项目维护人v1.0基础Lombok支持所有项目张三v1.1增加Swagger注解新开项目李四5.2 代码审查要点使用自定义模板后CR时应特别关注注解滥用检查避免过度使用Data导致性能问题文档一致性确认Swagger注解与实际接口行为匹配链式调用规范是否所有setter都正确返回this5.3 性能优化建议当实体类字段超过50个时考虑以下优化拆分为多个Getter/Setter分组对敏感字段单独配置Setter(AccessLevel.PRIVATE)使用Value替代Data创建不可变对象Value Builder ApiModel(精简实体) public class LiteEntity { ApiModelProperty(主键ID) Long id; ApiModelProperty(关键字段) String keyField; }6. 疑难问题解决方案6.1 注解不生效排查当Lombok注解无效时检查以下配置IDEA安装Lombok插件开启注解处理Settings → Build → Compiler → Annotation Processors确认依赖版本无冲突6.2 Swagger UI无法访问常见解决方案# application.properties配置 spring.mvc.pathmatch.matching-strategyant_path_matcher springfox.documentation.swagger-ui.base-url/api-docs6.3 模板调试技巧在模板中添加调试信息## 调试输出 #set($debug $tool.print($tableInfo)) !-- $debug --然后在生成的代码注释中查看表结构信息。