Что такое стремительная загрузка в Java? - PullRequest
4 голосов
/ 17 июня 2019

Я столкнулся с нетерпеливой загрузкой в ​​Java в двух классах Spring NestedRuntimeException и AbstractApplicationContext, оба эти случая решают одну и ту же проблему загрузчика классов с использованием статического блока кода, но способ их использования сбивает с толку.

Путаница связана с вызовом 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());

Любой экспертный совет будет оценен.

Ссылка

1 Ответ

4 голосов
/ 18 июня 2019

В первом случае, как показано ниже, 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");
    }
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...