• java类加载


    一、加载简单java对象 

    编写一个类,不依赖任何其他jar,如下

    package cc.eslink.bigscreen.controller.config;
    
    /**
     * @Author : wangbin
     * @Date : 2022/1/21 11:29
     * @Description:
     */
    public class User {
        private String name;
    
        public User() {
            System.out.println("create User!!!");
        }
    
        public void setName(String name){
            this.name=name;
        }
    
        public String getName(){
            return this.name;
        }
    }

    打成jar包,切记,一定打成原生jar包,不是胖jar

     /**
         * 经过一天的尝试,终于把类加载跑通了,之前失败N次的原因也找到了
         * 说来让人心酸,就是因为之前生成的胖jar包跟原生jar包格式不同
         * 使用类加载就要使用标准jar
         * @param args
         * @throws ClassNotFoundException
         * @throws IllegalAccessException
         * @throws InstantiationException
         * @throws IOException
         */
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, IOException {
            File file = new File("D:\\tlpi\\jar\\bigscreen-standard.jar");
            String className = "cc.eslink.bigscreen.controller.config.User";
            URL url = file.toURI().toURL();
            URLClassLoader classLoader = new URLClassLoader(new URL[]{url}, Thread.currentThread().getContextClassLoader());
            Class<?> aClass = classLoader.loadClass(className);
            aClass.newInstance();
    
    
        }

     输出:

    create User!!!

    二、加载一个依赖其他类的class

    我们知道在编程中完全不依赖第三方jar基本上是不可能的,那么我们的URLClassLoader能加载这些类吗?答案是可以

    我构造了一个新类,它有一些依赖的包

    package com.example.api.client.config;
    
    import com.example.api.gateway.exception.CachedException;
    import com.example.api.gateway.exception.FailedException;
    import com.example.api.gateway.filter.AbstractFilter;
    import com.example.api.gateway.handler.HttpMessage;
    
    /**
     * @Author : wangbin
     * @Date : 2022/1/21 14:38
     * @Description:
     */
    public class ThirdFilter extends AbstractFilter {
        @Override
        public HttpMessage filter(HttpMessage request) throws FailedException, CachedException {
            System.out.println("I am ThirdFilter");
            return null;
        }
    }

    我们在加载一次

     public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, IOException {
            File file = new File("D:\\tlpi\\jar\\bigscreen-standard.jar");
            String className = "com.example.api.client.config.ThirdFilter";
            URL url = file.toURI().toURL();
            URLClassLoader classLoader = new URLClassLoader(new URL[]{url}, Thread.currentThread().getContextClassLoader());
            Class<? extends AbstractFilter> aClass =( Class<? extends AbstractFilter>) classLoader.loadClass(className);
            AbstractFilter filter = aClass.newInstance();
            try {
                filter.filter(null);
            } catch (FailedException e) {
                e.printStackTrace();
            } catch (CachedException e) {
                e.printStackTrace();
            }
        }

    输出:I am ThirdFilter

    成功了,的确,但成功的很侥幸,因为ThirdFilter依赖的类恰好都在我们的JVM中,如果不在会怎样?

    三、加载一个依赖其他第三方我们不知道的jar的class

    为了验证我之前的猜测,我再ThirdFilter中加入一个我们现有环境中没有用过的类,代码如下:

    package com.example.api.client.config;
    
    import com.example.api.gateway.exception.CachedException;
    import com.example.api.gateway.exception.FailedException;
    import com.example.api.gateway.filter.AbstractFilter;
    import com.example.api.gateway.handler.HttpMessage;
    import org.jdom.Document;
    /**
     * @Author : wangbin
     * @Date : 2022/1/21 14:38
     * @Description:新加入org.jdom.Document
     */
    public class ThirdFilter extends AbstractFilter {
        @Override
        public HttpMessage filter(HttpMessage request) throws FailedException, CachedException {
            String simpleName = Document.class.getSimpleName();
            System.out.println(simpleName);
            System.out.println("I am ThirdFilter");
            return null;
        }
    }

    我们依然按照之前的方式进行类加载,不出所料,失败了

    Exception in thread "main" java.lang.NoClassDefFoundError: org/jdom/Document
        at com.example.api.client.config.ThirdFilter.filter(ThirdFilter.java:16)
        at com.example.api.gateway.utils.LoadUtil.main(LoadUtil.java:54)
    Caused by: java.lang.ClassNotFoundException: org.jdom.Document
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 2 more

    因为jvm中根本没有这个类的class,我们也没有告诉系统他的jar包在哪里。

    那么是不是我告诉系统这个jar包在哪里,他就能帮我找到,我修改了类加载的方法

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, IOException {
            File file = new File("D:\\tlpi\\jar\\bigscreen-standard.jar");
            String className = "com.example.api.client.config.ThirdFilter";
            URL url = file.toURI().toURL();
            File file1 = new File("D:\\tlpi\\jar\\jdom-1.1.3.jar");
            URL url1 = file1.toURI().toURL();
            URLClassLoader classLoader = new URLClassLoader(new URL[]{url,url1}, Thread.currentThread().getContextClassLoader());
            Class<? extends AbstractFilter> aClass =( Class<? extends AbstractFilter>) classLoader.loadClass(className);
            AbstractFilter filter = aClass.newInstance();
            try {
                filter.filter(null);
            } catch (FailedException e) {
                e.printStackTrace();
            } catch (CachedException e) {
                e.printStackTrace();
            }
        }

    输出:

    Document
    I am ThirdFilter

    成功了,证明我们的推测是正确的!

  • 相关阅读:
    【设计模式】责任链模式
    python 获取cookie,发送请求
    python requests报错:Exception: ('Connection broken: IncompleteRead(3794 bytes read, 4398 more expect ed)', IncompleteRea
    获取二维数组 所有的组合排列
    tp3.0 验证码生成和使用
    MySQL: mysql is not running but lock exists 的解决方法
    [RxSwift]4.2.0、Observer
    [RxSwift]4.1.6、ControlEvent
    [RxSwift]4.1.5、Signal
    [RxSwift]4.1.4、Driver
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/15830142.html
Copyright © 2020-2023  润新知