【问题标题】:How to prevent certain packages from using spring with ArchUnit?如何防止某些包在 ArchUnit 中使用 spring?
【发布时间】:2018-12-14 22:41:58
【问题描述】:

如果我想通过 ArchUnit 使某个 Java 包免于第三方依赖,我该怎么做?

更具体地说,我正在考虑将我的域模型保持在一个没有弹簧代码的六边形架构中。我指定了一些我认为应该阻止模型使用弹簧的规则。但是,我可以使用 @Component@Bean 之类的 spring 注释而不会导致违规。

到目前为止我尝试的是

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...

【问题讨论】:

    标签: java spring domain-driven-design hexagonal-architecture archunit


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      您也可以使用名称匹配。 所以你不必编写自定义的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"

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多