如何用ArchUnit验证@Startup类需含唯一@PostConstruct方法
ArchUnit规则验证@Startup类的@PostConstruct方法数量
需求说明
确保J2EE项目中被@Startup注解的类必须包含且仅包含一个被@PostConstruct注解的方法。
正确Kotlin实现代码
直接自定义Condition实现精确的数量校验,避免因依赖不存在的内置方法导致编译错误:
import com.tngtech.archunit.core.domain.JavaClass import com.tngtech.archunit.core.domain.JavaMethod import com.tngtech.archunit.junit.ArchTest import com.tngtech.archunit.lang.ArchRule import com.tngtech.archunit.lang.Condition import com.tngtech.archunit.lang.ConditionEvents import com.tngtech.archunit.lang.SimpleConditionEvent import jakarta.annotation.PostConstruct import jakarta.ejb.Startup @ArchTest val startup_classes_must_have_exactly_one_post_construct_method: ArchRule = classes() .that().areAnnotatedWith(Startup::class.java) .should(object : Condition<JavaClass>("have exactly one method annotated with @PostConstruct") { override fun check(item: JavaClass, events: ConditionEvents) { val postConstructMethods: List<JavaMethod> = item.methods.filter { it.isAnnotatedWith(PostConstruct::class.java) } when (postConstructMethods.size) { 0 -> events.add( SimpleConditionEvent.violated( item, "Class ${item.name} has no @PostConstruct method" ) ) 1 -> events.add( SimpleConditionEvent.satisfied( item, "Class ${item.name} has exactly one @PostConstruct method" ) ) else -> events.add( SimpleConditionEvent.violated( item, "Class ${item.name} has ${postConstructMethods.size} @PostConstruct methods (expected exactly one)" ) ) } } })
关键说明
- 自定义
Condition是因为ArchUnit没有直接提供shouldHaveExactlyOneMethodAnnotatedWith这类内置断言,手动实现数量校验更灵活且能避免编译错误。 - 代码通过过滤类的方法列表,统计
@PostConstruct注解方法的数量,分别处理0个、1个、多个三种场景,给出清晰的校验提示。 - 确保依赖正确引入(以Gradle为例):
testImplementation("com.tngtech.archunit:archunit-junit5:1.2.1") testImplementation("jakarta.ejb:jakarta.ejb-api:4.0.1") testImplementation("jakarta.annotation:jakarta.annotation-api:2.1.1")
内容的提问来源于stack exchange,提问作者MichaelM
相关产品推荐
相关产品推荐

