如何防止某些包在 ArchUnit 中使用 spring?
How to prevent certain packages from using spring with ArchUnit?
如果我想使用 ArchUnit 使某个 Java 包不受第 3 方依赖项的影响,我该怎么做?
更具体地说,我希望将我的领域模型保持在一个没有 spring 代码的六边形架构中。我指定了一些我认为应该阻止模型使用 spring 的规则。但是,我可以使用 spring 注释,例如 @Component
和 @Bean
而不会导致违规。
到目前为止我尝试的是
layeredArchitecture().
layer("domain").definedBy(DOMAIN_LAYER).
layer("application").definedBy(APPLICATION_LAYER).
layer("primary-adapters").definedBy(PRIMARY_ADAPTERS).
layer("secondary-adapters").definedBy(SECONDARY_ADAPTERS).
layer("spring").definedBy("org.springframework..")
whereLayer("spring").mayOnlyBeAccessedByLayers("primary-adapters", "secondary-adapters", "application").
because("Domain should be kept spring-free").
check(CLASSES);
以及
noClasses().that().resideInAPackage(DOMAIN_LAYER).
should().dependOnClassesThat().resideInAPackage("org.springframework..").
check(CLASSES);
noClasses().that().resideInAPackage(DOMAIN_LAYER).
should().accessClassesThat().resideInAPackage("org.springframework..").
check(CLASSES);
Here 一个可以很好地执行测试的代码示例,尽管 com.example.app.domain.Factory
正在导入 org.springframework...
.
您可以使用 DescribedPredicate:
void domainSpring() {
DescribedPredicate<JavaAnnotation> springAnnotationPredicate = new DescribedPredicate<JavaAnnotation>("Spring filter") {
@Override
public boolean apply(JavaAnnotation input) {
return input.getType().getPackageName().startsWith("org.springframework");
}
};
classes().that().resideInAPackage(DOMAIN_LAYER).should()
.notBeAnnotatedWith(springAnnotationPredicate).check(CLASSES);
}
您也可以使用名称匹配。
所以你不必写自定义 DescribedPredicate
.
ApplicationCoreMustNotDependOnFrameworks = noClasses()
.that().resideInAnyPackage(DOMAIN_LAYER)
.should().dependOnClassesThat().haveNameMatching("org.springframework.")
.orShould().dependOnClassesThat().haveNameMatching("javax.persistence.*")
.because("Domain should be free from Frameworks");
就我而言,我想要该规则的例外情况。
即,我没有完全排除 Spring,而是想在事件包 (EventHanlder
) 中接受 类
所以你可以用 "org.springframework(?!.*event).*"
替换 "org.springframework"
这是一个正则表达式
如果我想使用 ArchUnit 使某个 Java 包不受第 3 方依赖项的影响,我该怎么做?
更具体地说,我希望将我的领域模型保持在一个没有 spring 代码的六边形架构中。我指定了一些我认为应该阻止模型使用 spring 的规则。但是,我可以使用 spring 注释,例如 @Component
和 @Bean
而不会导致违规。
到目前为止我尝试的是
layeredArchitecture().
layer("domain").definedBy(DOMAIN_LAYER).
layer("application").definedBy(APPLICATION_LAYER).
layer("primary-adapters").definedBy(PRIMARY_ADAPTERS).
layer("secondary-adapters").definedBy(SECONDARY_ADAPTERS).
layer("spring").definedBy("org.springframework..")
whereLayer("spring").mayOnlyBeAccessedByLayers("primary-adapters", "secondary-adapters", "application").
because("Domain should be kept spring-free").
check(CLASSES);
以及
noClasses().that().resideInAPackage(DOMAIN_LAYER).
should().dependOnClassesThat().resideInAPackage("org.springframework..").
check(CLASSES);
noClasses().that().resideInAPackage(DOMAIN_LAYER).
should().accessClassesThat().resideInAPackage("org.springframework..").
check(CLASSES);
Here 一个可以很好地执行测试的代码示例,尽管 com.example.app.domain.Factory
正在导入 org.springframework...
.
您可以使用 DescribedPredicate:
void domainSpring() {
DescribedPredicate<JavaAnnotation> springAnnotationPredicate = new DescribedPredicate<JavaAnnotation>("Spring filter") {
@Override
public boolean apply(JavaAnnotation input) {
return input.getType().getPackageName().startsWith("org.springframework");
}
};
classes().that().resideInAPackage(DOMAIN_LAYER).should()
.notBeAnnotatedWith(springAnnotationPredicate).check(CLASSES);
}
您也可以使用名称匹配。
所以你不必写自定义 DescribedPredicate
.
ApplicationCoreMustNotDependOnFrameworks = noClasses()
.that().resideInAnyPackage(DOMAIN_LAYER)
.should().dependOnClassesThat().haveNameMatching("org.springframework.")
.orShould().dependOnClassesThat().haveNameMatching("javax.persistence.*")
.because("Domain should be free from Frameworks");
就我而言,我想要该规则的例外情况。
即,我没有完全排除 Spring,而是想在事件包 (EventHanlder
) 中接受 类
所以你可以用 "org.springframework(?!.*event).*"
替换 "org.springframework"
这是一个正则表达式