2

如果我想通过ArchUnit使某个 Java 包不受 3rd 方依赖项的影响,我该怎么做?

更具体地说,我正在考虑将我的域模型保持在一个没有弹簧代码的六边形架构中。我指定了一些我认为应该阻止模型使用弹簧的规则。但是,我可以像使用 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);

这里的代码示例可以很好地执行测试,尽管com.example.app.domain.Factory正在导入org.springframework....

4

2 回答 2

2

您可以使用 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);

}
于 2018-12-15T07:48:02.957 回答
1

您也可以使用名称匹配。因此,您不必编写 custom 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""org.springframework(?!.*event).*"正则表达式

于 2021-06-04T10:40:09.360 回答