如何在ArchUnit规则中仅允许调用EntityManager的detach方法?
ArchUnit规则实现:限制EntityManager的使用场景
针对你的需求,以下是两种符合要求的ArchUnit规则实现,基于JUnit 5环境:
方案1:仅允许com.myapp.EventService调用EntityManager.detach()
该规则会禁止所有非仓库类使用EntityManager,仅对EventService开放detach方法的调用权限。
import com.myapp.EventService; import jakarta.persistence.EntityManager; import com.tngtech.archunit.core.domain.JavaCall; import com.tngtech.archunit.lang.ArchRule; import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; public class PersistenceArchRules { private static final String REPOSITORY_PACKAGE = "com.myapp.repository.."; @ArchTest public static final ArchRule restrict_entity_manager_access_to_repos_and_eventservice_detach = noClasses() .that().doNotResideInAPackage(REPOSITORY_PACKAGE) .should().callMethodOn(EntityManager.class) .unless(call -> isEventServiceCallingDetach(call)); private static boolean isEventServiceCallingDetach(JavaCall<?> call) { return call.getCaller().getOwner().isAssignableTo(EventService.class) && call.getTargetMethod().getName().equals("detach"); } }
规则说明
- 核心逻辑:排除仓库包内的类后,禁止其他类调用
EntityManager的任何方法 - 例外判断:仅当调用方是
EventService且调用的方法是detach时,允许通过检查
方案2:允许仓库类以外的任意类仅调用EntityManager.detach()
该规则放宽了范围,所有非仓库类都可以调用detach方法,但禁止使用EntityManager的其他方法。
import jakarta.persistence.EntityManager; import com.tngtech.archunit.core.domain.JavaCall; import com.tngtech.archunit.lang.ArchRule; import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; public class PersistenceArchRules { private static final String REPOSITORY_PACKAGE = "com.myapp.repository.."; @ArchTest public static final ArchRule restrict_non_repo_entity_manager_calls_to_detach_only = noClasses() .that().doNotResideInAPackage(REPOSITORY_PACKAGE) .should().callMethodOn(EntityManager.class) .unless(call -> call.getTargetMethod().getName().equals("detach")); }
规则说明
- 核心逻辑:非仓库类调用
EntityManager时,仅允许detach方法 - 无需针对特定类做额外判断,所有非仓库类统一遵循此规则
内容的提问来源于stack exchange,提问作者Dónal
相关产品推荐
相关产品推荐

