自定义类加载器---支持同时加载jar包和文件夹中得类

自定义类加载器如下:

public class MyClassLoaderToJar extends ClassLoader{

    URLClassPath ucp;

    public MyClassLoaderToJar(URL[] urls) {
    	// 初始化一个资源工具,可加载jar包和文件夹中类
        ucp = new URLClassPath(urls);
    }

    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        if(!name.startsWith("com.jt")){
            return super.loadClass(name);
        }
        return findClass(name);
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {

        String path = name.replace(".", "/");
        Resource resource = ucp.getResource(path+".class", false);
        Class<?> aClass = null;
        try {
            byte[]  bytes = resource.getBytes();
             aClass = defineClass(name, bytes, 0, bytes.length);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (aClass == null) throw new ClassNotFoundException();
        return aClass;
    }
}

被加载类如下:

public class UserDemo {
    private String name;
    private int age;

    public UserDemo(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "UserDemo{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

测试类如下:

public class Demo {
	public static void main(String[] args) throws ClassNotFoundException, IOException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        MyClassLoaderToJar myClassLoaderToJar = new MyClassLoaderToJar(new URL[]{new URL("file:E:\\demo1\\demo1-1.0-SNAPSHOT.jar")});

        Class<?> aClass = myClassLoaderToJar.loadClass("com.learn.UserDemo");

        Constructor<?> constructor = aClass.getConstructor(String.class, int.class);
        Object o = constructor.newInstance("Tom", 12);
        System.out.println("classLoader:" + o.getClass().getClassLoader());
        System.out.println(o);
        Method setName = aClass.getDeclaredMethod("setName", String.class);
        setName.invoke(o, "jerry");

        System.out.println(o);

    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在一个应用程序同时两个版本的OJDBC驱动是比较困难的,因为Java类默认使用委派模型,即当一个类需要被时,它首先会请求其父类该类,如果父类无法该类,则由当前类尝试该类。 为了解决这个问题,我们可以使用自定义不同版本的OJDBC驱动。自定义可以绕过默认的委派模型,从而使得我们可以在同一个应用程序不同版本的类。 下面是一个简单的例子,演示如何使用自定义两个版本的OJDBC驱动: ```java import java.net.URL; import java.net.URLClassLoader; public class CustomClassLoader extends URLClassLoader { public CustomClassLoader(URL[] urls, ClassLoader parent) { super(urls, parent); } @Override public Class<?> loadClass(String name) throws ClassNotFoundException { if (name.startsWith("oracle.jdbc.")) { String version = System.getProperty("oracle.jdbc.version"); if (version != null && version.equals("11g")) { return loadClassFromVersion(name, "11g"); } else { return loadClassFromVersion(name, "12c"); } } return super.loadClass(name); } private Class<?> loadClassFromVersion(String name, String version) throws ClassNotFoundException { String className = name.replace(".", "/") + ".class"; URL url = getResource(className.replace(version, "common")); if (url == null) { throw new ClassNotFoundException(name); } byte[] bytes = null; try { bytes = IOUtils.toByteArray(url.openStream()); } catch (IOException e) { throw new ClassNotFoundException(name, e); } return defineClass(name, bytes, 0, bytes.length); } } ``` 在这个自定义,我们重写了loadClass方法,并根据系统属性oracle.jdbc.version的值来判断应该哪个版本的OJDBC驱动。 如果oracle.jdbc.version的值为11g,则11g版本的驱动,否则12c版本的驱动。 在loadClass方法,我们首先判断要的类是否以oracle.jdbc.开头,如果是,则调用loadClassFromVersion方法对应版本的类。 在loadClassFromVersion方法,我们首先使用getResource方法获取该类对应的URL,然后读取该URL对应的字节码,并使用defineClass方法将该类到内存。 最后,我们在应用程序使用自定义OJDBC驱动: ```java URL[] urls = new URL[] { new URL("file:///path/to/ojdbc11.jar"), new URL("file:///path/to/ojdbc12.jar") }; ClassLoader parent = ClassLoader.getSystemClassLoader(); CustomClassLoader loader = new CustomClassLoader(urls, parent); System.setProperty("oracle.jdbc.version", "11g"); // 设置oracle.jdbc.version属性为11g Class<?> driverClass = loader.loadClass("oracle.jdbc.driver.OracleDriver"); Driver driver = (Driver) driverClass.newInstance(); ``` 在这个例子,我们首先创建一个CustomClassLoader对象,并将ojdbc11.jar和ojdbc12.jar的URL作为参数传入。 然后,我们设置oracle.jdbc.version属性为11g,并使用CustomClassLoader对应版本的OracleDriver类,并创建该类的实例。 这样,我们就可以在同一个应用程序同时使用不同版本的OJDBC驱动了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值