开发者社区> 问答> 正文

自定义ClassLoader使用问题

public class MyClassLoader extends ClassLoader {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
    String path = null;
    String[] names = null;
    try {
        path = super.getSystemResource("").getPath();
        names = name.split("/");
        FileUtils.copyFile(new File(name), new File(path+"/"+(getPkgname()+"\\.").replaceAll("\\.", "/")+names[names.length-1]));
    } catch (IOException e) {
        e.printStackTrace();
    }
    String classname = getPkgname()+"."+names[names.length-1].split("\\.")[0];
    return super.getSystemClassLoader().loadClass(classname);
}

private String pkgname;
public String getPkgname() {
    return pkgname;
}
public void setPkgname(String pkgname) {
    this.pkgname = pkgname;
}
}
 public static void main(String[] args) throws SQLException {
        try {
            MyClassLoader my = new MyClassLoader();
            my.setPkgname("test");
            Class c = my.findClass("D:/Test2.class");
            Object o = c.newInstance();
            Method[] methods = c.getDeclaredMethods();
            for (int i = 0; i < methods.length; i++) {
                System.out.println(methods[i].getName());
                methods[i].invoke(o, null);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } 
package test;
public class Test2 {
public void printa(){
    System.out.println("xixi");
}
}

以上分别为自定义类,测试运行类和被加载类。
代码很简单,现在问题是类似这种加载classpath外的绝对路径的类java本身的ClassLoader没有这样的方法吗?然后我这样自定义的Classloader怎么在加载时启动?

展开
收起
蛮大人123 2016-05-26 17:09:19 2799 0
2 条回答
写回答
取消 提交回答
  • 技术源于生活

    继承一下URLClassLoader,之后这个类就只会加载你指定的url里面的jar包,在应用启动时候加载可以考试试试Thread.setCurrentTreadClassloader(你的classloader实例)

    2019-07-17 19:16:35
    赞同 展开评论 打赏
  • 我说我不帅他们就打我,还说我虚伪
    public class NetworkClassLoader extends URLClassLoader {  
      
        String baseUrl;  
      
        public String getBaseUrl() {  
            return baseUrl;  
        }  
      
        public void setBaseUrl(String baseUrl) {  
            this.baseUrl = baseUrl;  
        }  
      
        public NetworkClassLoader(){  
            this(new URL[]{});  
        }  
      
        /** 
         * URL 以'/'结尾的为目录 
         *     否则为jar包 
         *     未指定其父类加载器为系统类加载器 
         * @param urls 
         */  
        public NetworkClassLoader(URL[] urls) {  
            super(urls);  
        }  
        /** 
         * 同上,指定classLoader 
         * @param urls 
         * @param parent 
         */  
        public NetworkClassLoader(URL[] urls, ClassLoader parent) {  
            super(urls,parent);  
        }  
        /** 
         * 同上,URL工厂处理器 
         * @param urls 
         * @param parent 
         * @param factory 
         */  
        public NetworkClassLoader(URL[] urls, ClassLoader parent,  
                  URLStreamHandlerFactory factory) {  
             super(urls,parent,factory);  
        }  
      
        /** 
         * [添加baseUrl] 
         * @param url 
         */  
        public void addURL(String url){  
            URL uurl=null;  
            try {  
                uurl = new URL(baseUrl+url);  
            } catch (MalformedURLException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
            addURL(uurl);  
        }  
      
        /** 
         * 添加url[添加baseUrl] 
         */  
        protected void addURL(URL url) {  
            super.addURL(url);  
        }  
      
        /** 
         * 返回urls 
         */  
        public URL[] getURLs() {  
            return super.getURLs();  
        }  
      
        /** 
         * 查找类对象 
         *   从以上的URLS中查找加载当前类对象[会打开所有的jars去查找指定的类] 
         *   (可以通过调用findClass来得到以上URL加载包中的类) 
         */  
        protected Class<?> findClass(String name) throws ClassNotFoundException {  
            return super.findClass(name);  
        }  
        /** 
         * defineClass SecureClassLoader定义为最终方法,不允许更改. 
         * 在使用这个类对象前,必须先resolved(解析) 
         */  
        /** 
         * 查找资源[自定义相对URL查找路径] 
         *   从以上的URLS中查找当前名称的资源 
         * 这个必须重写,因为是public 哈哈 
         */  
        public URL findResource(String name) {  
            URL url = null;  
            try {  
                url = new URL(baseUrl+name);  
            } catch (MalformedURLException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
            return url;  
        }  
      
        /** 
         * 查找资源列表[URL查找路径] 
         */  
        public Enumeration<URL> findResources(String name) throws IOException {  
            return super.findResources(name);  
        }  
      
        /** 
         * 在当前的ClassLoader中,定义一个新的Package,Package的属性由Manifest指定.这个包的源文件 
         */  
        protected Package definePackage(String name, Manifest man, URL url)  
                throws IllegalArgumentException {  
            return super.definePackage(name, man, url);  
        }  
      
        /** 
         * 加载路径权限 
         */  
        protected PermissionCollection getPermissions(CodeSource codesource) {  
            return super.getPermissions(codesource);  
        }  
    }  

    以下是用法:

    NetworkClassLoader loader = new NetworkClassLoader();  
        loader.setBaseUrl("file:///F:\\框架\\maven\\app\\jms\\src\\main\\webapp\\modules\\");  
      
        loader.addURL("App/lib/test.jar");  
        loader.addURL("App/lib/test1.jar");  
        loader.addURL("App/template/view.vm");  
        loader.addURL("App/config.xml");  
    2019-07-17 19:16:35
    赞同 展开评论 打赏
问答分类:
问答地址:
相关产品:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载