0

我们通过一些 ArchUnit 规则检查我们的软件架构。

其中之一是对我们分层架构的测试。

这适用于方法。如果我们从 layer1 访问 layer3 的一个方法,我们会得到一个异常。

但是,如果从 layer1 访问在 layer3 中声明的字段,则不会引发异常。

   .layer("layer1").definedBy("com.acme.layer1")
   .layer("layer2").definedBy("com.acme.layer2")
   .layer("layer3").definedBy("com.acme.layer3")
   .whereLayer("layer3").mayNotBeAccessedByAnyLayer()
   .whereLayer("layer2").mayOnlyAccessedByLayers("layer3")
   .as("Respect the layered architecture");

如果我们将一个字段从 layer3 导入到 layer1 类,这不会抛出异常:

package com.acme.layer1

import static com.acme.layer3.SOME_LABEL

public class x {
   ...
}

我们的期望是,在任何其他层访问来自 layer3 的字段也应该引发异常。或者有其他方法可以检查吗?

4

1 回答 1

2

我的答案取决于假设com.acme.layer3.SOME_LABEL是一个常量表达式,例如public static final String SOME_LABEL = "..."

编译时常量在编译期间内联。如果您的代码看起来像

String label = SharedConstants.SOME_LABEL;

那么编译后的字节码包含SharedConstants.SOME_LABEL. 字节码中没有对该字段的引用。(静态最终内联陷阱

ArchUnit 通过分析字节码收集所有信息,另见ArchUnit 用户指南。因为SharedConstants.SOME_LABEL字节码中没有关于的信息,所以 ArchUnit 不知道这个访问。

总之:这是 ArchUnit 和所有其他仅依赖于字节码的库的限制。

于 2019-05-27T08:15:28.457 回答