如何创建自定义PMD规则检查循环中是否引用DSLContext实例?
自定义PMD规则(检测循环内DSLContext引用)实现指南
前置准备
- 环境要求:JDK 11+,PMD 7.x 稳定版,构建工具可选用Maven/Gradle,以下示例以Maven为准
- 项目引入PMD核心依赖,在
pom.xml中添加如下配置:
<dependency> <groupId>net.sourceforge.pmd</groupId> <artifactId>pmd-java</artifactId> <version>7.0.0</version> <scope>provided</scope> </dependency>
步骤1:编写规则实现类
自定义Java规则需继承AbstractJavaRule类,重写循环节点的访问方法,遍历循环内的变量引用匹配org.jooq.DSLContext类型:
import net.sourceforge.pmd.lang.java.ast.*; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; import org.jooq.DSLContext; public class DSLContextInLoopRule extends AbstractJavaRule { @Override public Object visit(ASTForStatement node, Object data) { checkForDSLContextReference(node, data); return super.visit(node, data); } @Override public Object visit(ASTWhileStatement node, Object data) { checkForDSLContextReference(node, data); return super.visit(node, data); } @Override public Object visit(ASTDoStatement node, Object data) { checkForDSLContextReference(node, data); return super.visit(node, data); } private void checkForDSLContextReference(JavaNode loopNode, Object data) { // 遍历当前循环下所有变量引用节点 loopNode.descendants(ASTVariableAccess.class) .forEach(varAccess -> { if (varAccess.getType() == DSLContext.class) { // 匹配到DSLContext引用,触发违规提示 asCtx(data).addViolation(varAccess, "禁止在循环内引用DSLContext实例,建议将DSL操作移到循环外批量执行"); } }); } }
步骤2:配置规则定义文件
在项目resources/pmd/rulesets/java目录下创建自定义规则集配置文件,命名为custom-jooq-rules.xml:
<?xml version="1.0"?> <ruleset name="自定义JOOQ规则集" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"> <description>JOOQ相关自定义检查规则</description> <rule name="DSLContextInLoop" language="java" class="com.yourpackage.DSLContextInLoopRule" message="禁止在循环内引用DSLContext实例" severity="WARNING"> <description>循环内重复引用DSLContext会导致不必要的资源开销,建议将批量操作移到循环外执行</description> </rule> </ruleset>
注意将com.yourpackage替换为你实际存放规则类的包名
步骤3:打包与使用规则
- 将规则项目打包为jar包
- 命令行使用PMD扫描时指定自定义规则集即可,示例命令:
pmd check -d /path/to/target/source/code -R pmd/rulesets/java/custom-jooq-rules.xml -f text - 如果是在Maven项目中集成PMD插件,只需在PMD插件的依赖中添加你打包的规则jar,同时指定上述规则集路径即可生效
调试验证参考
可以用以下测试代码验证规则是否生效:
// 违规示例代码 public void badCaseDemo() { DSLContext dsl = getDslContext(); for (int i = 0; i < 10; i++) { dsl.selectFrom("user").where("id = ?", i).fetch(); // 此处引用循环外DSLContext,会触发违规 } }
如果规则未正常触发,可优先检查规则类包名与XML配置的class路径是否一致,也可打印varAccess.getType().getName()确认类型匹配逻辑是否正确。
内容的提问来源于stack exchange,提问作者Niels Frederiksen
相关产品推荐
相关产品推荐

