You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ArchUnit编写JUnit测试检测Spring Boot Kotlin项目的反射使用?

用ArchUnit检测Spring Boot Kotlin项目中的反射使用

这个需求完全可行,ArchUnit通过字节码分析可以轻松检测代码中的反射调用,以下是具体实现方案:

1. 添加ArchUnit依赖

在你的Gradle或Maven配置中加入ArchUnit的JUnit 5依赖(以Gradle Kotlin DSL为例):

testImplementation("com.tngtech.archunit:archunit-junit5:1.2.1")
testImplementation("com.tngtech.archunit:archunit-core:1.2.1")

2. 编写JUnit测试用例

核心是通过ArchUnit的规则,禁止项目代码调用Java或Kotlin的反射API。下面是完整的测试类示例:

import com.tngtech.archunit.core.domain.JavaClasses
import com.tngtech.archunit.core.importer.ClassFileImporter
import com.tngtech.archunit.lang.ArchRule
import com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses
import org.junit.jupiter.api.Test

class ReflectionUsageCheckTest {

    // 导入你项目的根包,替换成实际路径
    private val projectClasses: JavaClasses = ClassFileImporter().importPackages("com.your.project.root")

    @Test
    fun `禁止使用Java反射API`() {
        val javaReflectionRule: ArchRule = noClasses()
            // 禁止调用Class类的反射相关方法
            .should().callMethodOn(Class::class.java)
            .withNameMatching("forName|getMethod|getDeclaredMethod|getField|getDeclaredField|getConstructor|getDeclaredConstructor")
            // 禁止调用Method/Field/Constructor的反射执行方法
            .orShould().callMethodOnAnyOf(
                java.lang.reflect.Method::class.java,
                java.lang.reflect.Field::class.java,
                java.lang.reflect.Constructor::class.java
            )
            .withNameMatching("invoke|get|set|newInstance")

        javaReflectionRule.check(projectClasses)
    }

    @Test
    fun `禁止使用Kotlin反射API`() {
        val kotlinReflectionRule: ArchRule = noClasses()
            // 禁止访问kotlin.reflect包下的类或调用其中的方法
            .should().accessClassesThat().resideInAPackage("kotlin.reflect..")
            .orShould().callMethodOnClassesThat().resideInAPackage("kotlin.reflect..")

        kotlinReflectionRule.check(projectClasses)
    }
}

3. 自定义规则(可选)

如果有某些类或包需要允许使用反射(比如特定的配置类),可以通过that()和doNot...来排除:

// 排除名为ReflectionAllowedConfig的类
val rule: ArchRule = noClasses()
    .that().doNotHaveSimpleName("ReflectionAllowedConfig")
    .should().callMethodOn(Class::class.java)
    .withNameMatching("forName")

或者排除整个包:

// 允许com.your.project.allowed包下的类使用反射
val rule: ArchRule = noClasses()
    .that().resideOutsideOfPackage("com.your.project.allowed..")
    .should().callMethodOn(Class::class.java)
    .withNameMatching("forName")

注意事项

  • 确保导入的是你项目的根包,这样ArchUnit只会扫描你自己编写的代码,不会检测Spring框架等第三方依赖中的反射使用。
  • 可以根据实际需求调整规则中的方法名匹配,比如添加更多反射相关方法的名称。

内容的提问来源于stack exchange,提问作者Abhi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 09:35:29