自定义类加载器加载冲突类(二)-URLClassLoader

描述

之前直接继承ClassLoader, 单独加载类,且有依赖的时候会比较麻烦。

此处使用URLClassLoader(ClassLoader的子类SecureClassLoader的子类)加载整个lib,并调用其中的方法。这样即使jar包有多个版本,且我们都想要使用其中的方法,也可以满足。

代码

package com.hz.classloader;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;

/**
 * @description: 使用URLClassLoader加载
 * @author: pp_lan
 * @date: 2022/3/17
 */
public class UrlExternalClasspathLoader {

    private static final Logger LOGGER = LoggerFactory.getLogger(UrlExternalClasspathLoader.class);

    private URLClassLoader urlClassLoader;

    /**
     * 构造方法
     * @param file jar所在的路径,或者单个jar的全路径
     */
    public UrlExternalClasspathLoader(File file) {
        List<URL> urlList = new ArrayList<>();
        if (file.isDirectory()) {
            addUrl(urlList, file);
        } else {
            addJar(urlList, file);
        }

        URL[] urls = urlList.toArray(new URL[]{});
        urlClassLoader = new URLClassLoader(urls);
    }

    /**
     * 加载class
     * @param name
     * @return
     * @throws ClassNotFoundException
     */
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        return this.urlClassLoader.loadClass(name);
    }

    /**
     * 加载路径
     * @param urlList
     * @param file
     */
    private void addUrl(List<URL> urlList, File file) {
        File[] subFiles = file.listFiles();
        if (subFiles != null) {
            for (File subFile : subFiles) {
                if (subFile.isDirectory()) {
                    addUrl(urlList, subFile);
                } else {
                    addJar(urlList, subFile);
                }
            }
        }
    }

    /**
     * 加载jar
     * @param urlList
     * @param subFile
     */
    private void addJar(List<URL> urlList, File subFile) {
        try {
            if (subFile.getAbsolutePath().endsWith(".jar")) {
                urlList.add(subFile.toURI().toURL());
            }
        } catch (MalformedURLException e) {
            LOGGER.error("【加载JAR异常】", e);
        }
    }

    public static void main(String[] args) {
        LOGGER.info("开始");
        UrlExternalClasspathLoader classLoader1 = new UrlExternalClasspathLoader(new File("E:\\git-workspace\\mercury-new\\app\\lib\\"));
        UrlExternalClasspathLoader classLoader2 = new UrlExternalClasspathLoader(new File("E:\\git-workspace\\mercury-new\\app\\lib\\"));
        try {
            Class<?> aClass1 = classLoader1.loadClass("com.zzz.common.api.tool.ApiUtil");
            Method nullOrEmpty1 = aClass1.getMethod("nullOrEmpty", String.class);
            Object invoke11 = nullOrEmpty1.invoke(aClass1, "123");
            Object invoke12 = nullOrEmpty1.invoke(aClass1, "");
            Object invoke13 = nullOrEmpty1.invoke(aClass1, "null");

            Class<?> aClass2 = classLoader2.loadClass("com.zzz.common.api.tool.ApiUtil");
            Method nullOrEmpty2 = aClass2.getMethod("nullOrEmpty", String.class);
            Object invoke21 = nullOrEmpty2.invoke(aClass1, "123");

            // 执行结果
            LOGGER.info("【结果】11: {}, 12: {}, 13: {}.", invoke11, invoke12, invoke13);
            LOGGER.info("【结果】21: {}.", invoke21);

        } catch (Exception e) {
            LOGGER.error("ClassLoader调用方法失败", e);
        }
    }
}

说明

  1. 添加一个路径或者一个jar包,到URLClassLoader对象中,
  2. 使用时候直接调用loadClass方法获取Class对象
  3. 再使用反射进行调用

调用目的方法

 执行结果

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值