我们通过一些ArchUnit规则检查我们的软件架构。
其中之一是对我们的分层体系结构的测试。
这对于方法很好用。 如果我们从第1层访问第3层的方法,则会得到异常。
但是,如果从第1层访问第3层中声明的字段,则不会引发异常。
.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访问字段也应引发异常。 还是还有另一种检查方法?
答案 0 :(得分:0)
我的回答取决于com.acme.layer3.SOME_LABEL
是constant expression像public static final String SOME_LABEL = "..."
的假设
在编译期间内联编译时常量。如果您的代码看起来像
String label = SharedConstants.SOME_LABEL;
然后编译的字节码包含SharedConstants.SOME_LABEL
的精确值。字节码中没有对该字段的引用。 (The Static Final Inline Trap)
ArchUnit通过分析字节码来收集所有信息,另请参见ArchUnit User Guide。因为字节码中没有关于SharedConstants.SOME_LABEL
的信息,所以ArchUnit不知道这种访问。
总结:这是ArchUnit和所有其他仅依赖字节码的库的限制。