使用耳内反射改变静态场

时间:2018-05-09 07:47:00

标签: java spring reflection

一个EAR包含2个WAR(WAR1,WAR2)这两个WARS都有一个依赖jar(JAR1)。

JAR1有一个类(CLASS1),其中有一个静态字段private String STATIC1 = "DEFAULT_VAL";,它适用于WAR2,但不适用于适用于WAR1。所以我在WAR1中添加了一项服务来修改它:

@Service
public class ModService {
    @PostConstruct
    public void modMyVal() {
        Field declaredField = CLASS1.class.getDeclaredField("STATIC1");
        declaredField.setAccessible(true);
        declaredField.set(this, "NEW_VAL_FOR_WAR1");
    }
}

令我惊讶的是,在WAR2中一切正常。我期待WAR2有NEW_VAL_FOR_WAR1。两个WAR都加载在同一个耳内,jvm,服务器 - 它们都依赖于同一个jar。如何为WAR2改变静态字段?

很少有其他指示:

  • Jar1由第三方提供,因此无法控制来源。
  • Jar1驻留在WAR1 / WEB-INF / lib& WAR2 / WEB-INF / lib中
  • 服务器是weblogic。
  • 我很高兴它有效:)。但好奇的是它如何在内部工作,以及什么节省了我的一天。

2 个答案:

答案 0 :(得分:2)

两个WAR都有自己的类加载器。从JAR为每个WAR加载一次类为Class提供2个实例,因此您的WAR可以看到成员变量的“他们的版本”而不是您期望的共享状态。

你也可以想象一下这种hackery会导致什么样的错误,所以我会避免养成这种习惯。

答案 1 :(得分:0)

Tomcat使用不同的WebAppClassLoader加载不同的webapp上下文。换句话说,WAR1中的类与WAR2中的类不同,尽管它们具有相同的包和类名。

因此WAR1中的CLASS1.class与WAR2中的CLASS1.class不同。当然,WAR1.CLASS1中的set字段不会影响WAR2.CLASS1。