28 июня 2019
Для загрузки классов во время выполнения java используют механизм ClassLoader, который основан на нескольких основных принципах:
parent-first delegation
, - наследник ClassLoader будет использоваться, если родитель не может найти или загрузить класс. Это поведение можно изменить на child-first
, переписав ClassLoader.loadClass(...)
;Основные сценарии использования пользовательского ClassLoader:
Итак, давайте посмотрим, как выглядит использование пользовательского ClassLoader с точки зрения исходного кода:
List<File> jars = Arrays.asList(new File("/tmp/jars").listFiles());
URL[] urls = new URL[files.size()];
for (int i = 0; i < jars.size(); i++) {
try {
urls[i] = jars.get(i).toURI().toURL();
} catch (Exception e) {
e.printStackTrace();
}
}
URLClassLoader childClassLoader = new URLClassLoader(urls, ClassLoader.getSystemClassLoader());
Затем загрузите класс с пользовательским ClassLoader:
Class.forName("org.kostenko.examples.core.classloader.ClassLoaderTest", true , childClassLoader);
Обратите внимение! Если ваши загруженные библеотеки используют некоторые ресурсы, такие как свойства или что-то ещё, вам нужно продоставить загрузчик класса котекста:
Thread.currentThread().setContextClassLoader(childClassLoader);
Кроме того, вы можете использовать пользовательские ClassLoaders для загрузки служб с помощью Java Service Provider Interface(SPI)
ServiceLoader<MyProvider> serviceLoader = ServiceLoader.load(MyProvider.class, childClassLoader);
...