最近由于项目需要,需要来加载jar包的模块并且jar包的模块需要互相隔离,自然需要一个自定义的classloader。由于对classloader了解不多,决定继承URLClassLoader类,并暴露addURL等方法。
public class ServerClassLoad extends URLClassLoader{ public ServerClassLoad(URL[] urls, ClassLoader parent) { super(urls,parent); } @Override public void addURL(URL url) { super.addURL(url); } .... }
将当前的Classpath加入到classLoader中。
URL url = (new File(classpath + "/" + name)).toURL(); URL urllib = (new File(classpath + "/lib")).toURL(); //url urllib为获取当前的应用的classPath ServerClassLoad currentLoader = new ServerClassLoad(new URL[]{url,urllib},Thread.currentThread().getContextClassLoader());
Java类非常简单,但是在加载用Spring启动的文件时出现了问题,无法使用Spring的ClassPathXmlApplicationContext启动Spring容器时,发现当前的ClassLoader可以找到启动类,但是无法启动Spring容器。报错为无法找到ApplicationContext文件。
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [applicationContext.xml]; nested exception is java.io.FileNotFoundException: class path resource [applicationContext.xml] cannot be opened because it does not exist
参考网上大神们的解释得知,classLoader存在一种线程上下文加载器,Spring容器启动时需要上下文加载器的帮助,设置上下文加载器为当前新建类加载器。
//将当前的应用加载器设置为线程上下文加载器 Thread.currentThread().setContextClassLoader(currentLoader);
应用启动成功,但目前未了解Spring何时需要应用ContextClassLoader。希望有大神可以给予一些帮助。