IntelliJ IDEA结构搜索:关联带@CustomAnnotate的Repository与CrudRepository方法调用
解决IntelliJ IDEA结构搜索关联条件的问题
我之前折腾过IntelliJ结构搜索的关联过滤需求,刚好能帮你解决这个问题——要同时找到调用了带@CustomAnnotate注解的CrudRepository方法的服务类,你之前的问题大概率是关联模板的配置细节没到位,下面分两种方案给你讲:
方案一:用IntelliJ自带的结构搜索关联模板
这个是最推荐的,不用写脚本,配置好两个关联的模板就行:
第一步:创建并保存Repository的搜索模板
先定义“带@CustomAnnotate的Spring Repository”的模板,方便后面引用:
- 打开
Edit > Find > Search Structurally - 点击
+新建模板,选择Java语言 - 输入模板代码:
@CustomAnnotate interface $RepoInterface$ extends CrudRepository<$EntityType$, $IdType$> { }
- 配置每个变量的过滤器:
$RepoInterface$:设置“应用于:接口”,确保只匹配接口类型- 点击
Save Template,命名为CustomAnnotatedCrudRepo(这个名字后面要用到)
第二步:创建服务调用的关联搜索模板
接下来定义服务类中调用该Repository方法的模板:
- 再次新建一个Java结构搜索模板,输入代码:
@Service class $ServiceClass$ { $RepoInstance$ $repoField$; void $ServiceMethod$() { $repoField$.$CrudMethod$($Params$); } }
逐个配置变量过滤器:
$RepoInstance$:点击变量右侧的...,选择“类型”,然后在“类型过滤器”里选“引用已保存的模板”,找到刚才保存的CustomAnnotatedCrudRepo,这样就限定了这个变量的类型必须是带@CustomAnnotate的Repository$CrudMethod$:设置“名称匹配”为findById|findAll|save|delete(根据你要找的Crud方法调整),同时勾选“方法所属类型”并输入org.springframework.data.repository.CrudRepository,确保只匹配CrudRepository的方法$Params$:设置“出现次数”为0, ∞,允许方法有任意参数$ServiceClass$:设置“应用于:类”,并可选添加“注解:@Service”来限定服务类
点击
Find就能找到所有符合条件的服务类调用了!
为什么你之前的配置没生效?
大概率是$REPO$的过滤器没设置对:你需要确保$REPO$的类型是引用第一个模板的结果,而不是直接用“文本匹配”或者其他过滤方式。另外,最好把调用上下文限定在服务类里,避免搜到其他无关的调用。
方案二:用Groovy脚本扩展IntelliJ Inspection
如果结构搜索的灵活性不够(比如需要更复杂的逻辑),可以写一个自定义Inspection脚本:
- 打开
File > Settings > Tools > Scripted Extensions > Inspection Scripts - 点击
+新建Groovy脚本,命名为CustomRepoUsageChecker.groovy - 粘贴下面的脚本(记得替换你的注解包名):
import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool import com.intellij.codeInspection.ProblemsHolder import com.intellij.psi.* import com.intellij.psi.impl.source.PsiClassReferenceType import com.intellij.psi.util.PsiTypesUtil import com.intellij.psi.annotation.PsiAnnotation class CustomRepoUsageChecker extends AbstractBaseJavaLocalInspectionTool { @Override PsiElementVisitor buildVisitor(ProblemsHolder holder, boolean isOnTheFly) { return new JavaElementVisitor() { @Override void visitMethodCallExpression(PsiMethodCallExpression call) { super.visitMethodCallExpression(call) // 1. 检查调用的方法是否属于CrudRepository def targetMethod = call.resolveMethod() if (!targetMethod) return def methodClass = targetMethod.containingClass def crudRepoClass = JavaPsiFacade.getInstance(holder.project) .findClass("org.springframework.data.repository.CrudRepository", holder.scope) if (!methodClass?.isInheritor(crudRepoClass, true)) return // 2. 检查调用的实例类型是否带@CustomAnnotate def qualifier = call.methodExpression.qualifierExpression if (!qualifier) return def instanceType = qualifier.type if (!(instanceType instanceof PsiClassReferenceType)) return def repoClass = PsiTypesUtil.getPsiClass(instanceType) def customAnnot = repoClass?.getAnnotation("com.yourpackage.CustomAnnotate") if (!customAnnot) return // 3. 检查所在类是否是服务类 def serviceClass = qualifier.containingClass if (!serviceClass?.getAnnotation("org.springframework.stereotype.Service")) return // 标记符合条件的调用 holder.registerProblem(call, "调用了带@CustomAnnotate的CrudRepository方法") } } } }
- 保存后,回到代码界面,打开
Analyze > Inspect Code,在检查列表里找到你新建的脚本,运行就能得到结果。
这个脚本的好处是可以自定义更复杂的逻辑,比如检查方法参数、返回值,或者其他注解条件。
内容的提问来源于stack exchange,提问作者Eliot
相关产品推荐
相关产品推荐

