最近由于项目需要,需要来加载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。希望有大神可以给予一些帮助。