使用 ArchUnit 限制对静态方法的访问
Restricting access to static methds with ArchUnit
在我们的架构指南中,我们应该只在域模型或存储库实现(位于基础设施层)中实例化业务异常
我们通常使用工厂方法创建异常。
所以我想为此制定一个 ArchUnit 规则。应该遵循以下原则:
只有驻留在 domain
中的 classes 或者是 Repositories
的实现才能大声调用带有 @BusinessException
注释的 classes 的静态方法
我们所有的业务异常都带有@BusinessException 注释。所以很容易找到它们。
我尝试了它的变体:
noClasses().that().resideOutsideOfPackages(DOMAIN).or(areImplementing(Repository.class))
.should().callMethodWhere(
target(owner(isAnnotatedWith(BusinessException.class)))
.and(target(modifier(JavaModifier.STATIC))));
areImplementing()
是一个自定义谓词,用于确定 class 是否是存储库的实现。
此代码无法编译。 isAnnotatedWith
不能这样用
我也尝试了
的变体
methods().that().areStatic()
.and().areDeclaredInClassesThat().areAnnotatedWith(BusinessException.class)
.should().onlyBeCalled().byClassesThat(areImplementing(Repository.class))
同样,这不编译,onlyBeCalled
不存在。
有人有想法吗?
我不完全确定是否有更短的形式来表达您想要的内容,但我相信以下使用自定义谓词的代码片段可以完成这项工作。
noClasses().that()
// Restriction applies to all classes outside DOMAIN package that are not Repository classes
.resideOutsideOfPackages(DOMAIN)
.and()
.areNotAssignableFrom(Repository.class)
.should()
.callMethodWhere(describe("static methods in BusinessExceptions",
// Target method may not reside in class annotated with BusinessException
methodCall -> methodCall.getTarget().getOwner().isAnnotatedWith(BusinessException.class)
// And target method may not have the static modifier
&& methodCall.getTarget()
.resolve()
.stream()
.anyMatch(m -> m.getModifiers().contains(JavaModifier.STATIC))));
我唯一不确定的是 methodCall.getTarget().resolve()
returns 一组 JavaMethod 类.
在我们的架构指南中,我们应该只在域模型或存储库实现(位于基础设施层)中实例化业务异常
我们通常使用工厂方法创建异常。
所以我想为此制定一个 ArchUnit 规则。应该遵循以下原则:
只有驻留在 domain
中的 classes 或者是 Repositories
的实现才能大声调用带有 @BusinessException
我们所有的业务异常都带有@BusinessException 注释。所以很容易找到它们。
我尝试了它的变体:
noClasses().that().resideOutsideOfPackages(DOMAIN).or(areImplementing(Repository.class))
.should().callMethodWhere(
target(owner(isAnnotatedWith(BusinessException.class)))
.and(target(modifier(JavaModifier.STATIC))));
areImplementing()
是一个自定义谓词,用于确定 class 是否是存储库的实现。
此代码无法编译。 isAnnotatedWith
不能这样用
我也尝试了
的变体methods().that().areStatic()
.and().areDeclaredInClassesThat().areAnnotatedWith(BusinessException.class)
.should().onlyBeCalled().byClassesThat(areImplementing(Repository.class))
同样,这不编译,onlyBeCalled
不存在。
有人有想法吗?
我不完全确定是否有更短的形式来表达您想要的内容,但我相信以下使用自定义谓词的代码片段可以完成这项工作。
noClasses().that()
// Restriction applies to all classes outside DOMAIN package that are not Repository classes
.resideOutsideOfPackages(DOMAIN)
.and()
.areNotAssignableFrom(Repository.class)
.should()
.callMethodWhere(describe("static methods in BusinessExceptions",
// Target method may not reside in class annotated with BusinessException
methodCall -> methodCall.getTarget().getOwner().isAnnotatedWith(BusinessException.class)
// And target method may not have the static modifier
&& methodCall.getTarget()
.resolve()
.stream()
.anyMatch(m -> m.getModifiers().contains(JavaModifier.STATIC))));
我唯一不确定的是 methodCall.getTarget().resolve()
returns 一组 JavaMethod 类.