我在Spring NestedRuntimeException
和AbstractApplicationContext
的两个类中遇到了Java的急切加载,这两种情况都使用静态代码块解决了相同的Class loader问题,但是使用它们的方式是令人困惑。
困惑是关于在静态代码块中对ClassName.class.getName()
的调用,这如何解决类加载器问题。
static {
// Eagerly load the ContextClosedEvent class to avoid weird classloader issues
// on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
ContextClosedEvent.class.getName();
}
如果我要这样做,我将获得类加载器并手动加载该类
Thread.currentThread()
.getContextClassLoader().loadClass(ContextClosedEvent.class.getName());
任何专家的建议将不胜感激。
答案 0 :(得分:4)
在第一种情况下,例如下面的示例,ContextClosedEvent
将在使用YourClass
后立即加载。
class YourClass {
static {
// Eagerly load the ContextClosedEvent class to avoid weird classloader issues
// on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
ContextClosedEvent.class.getName();
}
}
第二种情况,ContextClosedEvent
将在您的代码运行时加载,loadClass
方法将被调用2次。第一次是供ContextClosedEvent.class
参考(由JVM调用),第二次是您的手动调用。
第一次ContextClosedEvent
实际上是从类路径加载的。第二次,这取决于您的ContextClassLoader
。默认情况下,JVM的类加载器将findLoadedClass
而不是再次加载该类。
作为下面的示例,loadClass
方法运行时将调用main
方法两次。
class Main {
public static void main(String[] args) throws ClassNotFoundException {
Thread.currentThread()
.getContextClassLoader().loadClass(ContextClosedEvent.class.getName());
}
}
要查看静态块的工作原理,请运行以下示例
class Main {
public static void main(String[] args) {
System.out.println("main method invoked");
}
static {
System.out.println("static block invoked");
}
}