如何用ArchUnit限制类使用被Qualifier注解标注的自定义注解?
用ArchUnit实现禁止类使用被@Qualifier标注的自定义注解的架构约束
需求背景
需要实现架构约束:禁止项目中的类使用任何被javax.inject.Qualifier注解标注的自定义注解,替代原有的Java反射实现方案。
实现步骤
1. 引入ArchUnit依赖
如果使用Maven,在pom.xml中添加依赖:
<dependency> <groupId>com.tngtech.archunit</groupId> <artifactId>archunit-junit5</artifactId> <version>1.2.1</version> <scope>test</scope> </dependency>
2. 编写ArchUnit规则
创建测试类,编写对应的架构约束规则:
import com.tngtech.archunit.core.domain.JavaAnnotation; import com.tngtech.archunit.core.domain.JavaClass; import com.tngtech.archunit.core.importer.ClassFileImporter; import com.tngtech.archunit.core.importer.ImportOption; import com.tngtech.archunit.lang.ArchRule; import org.junit.jupiter.api.Test; import javax.inject.Qualifier; import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; public class ArchitectureConstraintsTest { @Test void classesShouldNotUseQualifierAnnotatedCustomAnnotations() { // 导入项目指定包下的所有类(可按需调整导入范围) var importedClasses = new ClassFileImporter() .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_JARS) .importPackages("your.base.package"); // 筛选出所有被@Qualifier标注的自定义注解 var qualifierAnnotations = importedClasses.getAnnotations() .stream() .filter(annotation -> annotation.isAnnotatedWith(Qualifier.class)) .map(JavaAnnotation::getRawType) .toList(); // 定义规则:禁止任何类使用这些自定义Qualifier注解 ArchRule rule = noClasses() .should().beAnnotatedWithAnyOf(qualifierAnnotations.toArray(new Class[0])) .because("类禁止使用被@Qualifier标注的自定义注解"); // 执行规则检查,违规时会抛出详细异常 rule.check(importedClasses); } }
代码说明
- 类导入:通过
ClassFileImporter导入指定包下的类,排除第三方JAR包避免误判非自定义的Qualifier注解。 - 注解筛选:从导入的元数据中过滤出被
@Qualifier标注的自定义注解,提取它们的Class对象。 - 规则声明:用ArchUnit的DSL语法明确约束逻辑,同时添加违规原因,方便后续定位问题。
- 规则执行:运行测试时,ArchUnit会自动检查所有类,若存在违规会抛出包含具体违规类和注解的异常。
对比原反射实现
相比原反射方案,ArchUnit实现的优势:
- 天然集成JUnit测试框架,可融入现有测试流程自动执行。
- 规则声明更直观,DSL语法可读性强,便于团队维护。
- 违规报告更精准,直接给出违规类和对应注解的信息,无需手动遍历输出。
内容的提问来源于stack exchange,提问作者Codinggeek
相关产品推荐
相关产品推荐

