ArchUnit 架构治理神器(Java )
·
ArchUnit 介绍
是什么
ArchUnit 是一个专门用于 Java 架构测试的开源库,由德国 TNG Technology Consulting 公司开发维护。
核心理念:把架构约束写成代码,像跑单元测试一样验证架构是否被遵守。
- GitHub:https://github.com/TNG/ArchUnit
- License:Apache 2.0
- 当前版本:1.x(持续活跃维护)
解决什么问题
在实际项目中,架构规范往往只存在于文档和口头约定中:
"Controller 层不能直接调 Repository"
"Service 不能依赖 Web 层"
"util 包不能依赖 domain 包"
但这些约定没有任何强制力——开发者一忙就忘了,或者新来的人压根不知道。时间长了,架构腐化,依赖混乱。
ArchUnit 的解法:把这些规则写成测试代码,CI/CD 每次构建时自动验证,违规直接失败。
核心能力
| 能力 | 说明 |
|---|---|
| 包依赖检查 | 检查包之间的依赖关系是否合规 |
| 分层架构验证 | 验证 Controller → Service → Repository 单向依赖 |
| 循环依赖检测 | 自动发现包之间的循环引用 |
| 命名规范检查 | 检查类名、方法名是否符合约定 |
| 注解使用规范 | 某些注解只能用在特定包/类型上 |
| 继承/实现规范 | 检查接口实现、类继承关系约束 |
| 调用关系检查 | 某些类不允许被其他类调用 |
代码示例
1. 分层架构验证(最常用)
java
复制
@Test
public void 分层架构应遵守单向依赖() {
JavaClasses classes = new ClassFileImporter()
.importPackages("com.myapp");
layeredArchitecture()
.consideringAllDependencies()
.layer("Controller").definedBy("..controller..")
.layer("Service").definedBy("..service..")
.layer("Repository").definedBy("..repository..")
// Controller 只能被外部访问
.whereLayer("Controller").mayNotBeAccessedByAnyLayer()
// Service 只能被 Controller 访问
.whereLayer("Service").mayOnlyBeAccessedByLayers("Controller")
// Repository 只能被 Service 访问
.whereLayer("Repository").mayOnlyBeAccessedByLayers("Service")
.check(classes);
}
2. 命名规范检查
java
复制
@Test
public void Service类应以Service结尾() {
classes()
.that().resideInAPackage("..service..")
.should().haveSimpleNameEndingWith("Service")
.check(classes);
}
@Test
public void Controller类应该带RestController注解() {
classes()
.that().haveSimpleNameEndingWith("Controller")
.should().beAnnotatedWith(RestController.class)
.check(classes);
}
3. 禁止依赖检查
java
复制
@Test
public void Service层不能直接依赖Controller层() {
noClasses()
.that().resideInAPackage("..service..")
.should().dependOnClassesThat()
.resideInAPackage("..controller..")
.check(classes);
}
4. 循环依赖检测
java
复制
@Test
public void 包之间不应存在循环依赖() {
slices()
.matching("com.myapp.(*)..")
.should().beFreeOfCycles()
.check(classes);
}
与主流框架集成
xml
复制
<!-- Maven 引入 -->
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit-junit5</artifactId>
<version>1.3.0</version>
<scope>test</scope>
</dependency>
支持:
- JUnit 4 / JUnit 5(最常用)
- TestNG
- Spring Boot Test 无缝集成
技术原理
源码/字节码
↓
ClassFileImporter(字节码解析)
↓
JavaClasses(内存中的类模型)
↓
规则引擎(fluent API 描述规则)
↓
违规收集 → 断言失败 → 输出清晰报错信息
ArchUnit 通过直接分析 .class 字节码文件,不依赖源码,不需要运行时反射,性能好且精确。
适用场景
| 场景 | 描述 |
|---|---|
| 团队规范落地 | 新人入职规范自动检查,无需 Code Review 强制把关 |
| 微服务架构守护 | 确保各模块间依赖边界不被越界调用 |
| 遗留系统治理 | 梳理现有代码依赖关系,发现架构腐化点 |
| CI/CD 卡口 | 架构违规直接阻断构建流水线 |
优缺点
| 优点 | 缺点 |
|---|---|
| 零侵入,纯测试代码 | 只支持 Java/Kotlin/Groovy(JVM 系语言) |
| 上手简单,Fluent API 可读性强 | 规则需要人工维护 |
| 与 JUnit/CI 无缝集成 | 大型项目首次扫描略慢 |
| 报错信息清晰,定位准确 | 动态代理类可能误报,需要排除配置 |
一句话总结
ArchUnit 就是给架构设计加了一道自动化防火墙,让团队的架构约定不再只是口头承诺,而是每次构建都会自动执行的测试守卫。
特别适合技术规范落地难、团队协作经验不一致的中大型项目。有架构管理诉求的团队强烈推荐引入。
更多推荐

所有评论(0)