自定义类加载器(自定义类加载器的作用)

java自定义classloader在加载jar包和classes的时候,classloader不能找到classpath下的配置文件

设我们有一个hello.jar文件,里面有一个Util类,我们希望在运行期调将这个jar包放入到我们运行环境并且调用里面的Util.getVersion方法。怎么实现?

在java中,我们的类都是通过ClassLoader来加载的,同时ClassLoader具有层级关系,当某个类找不到时,它会去他的父类加载器去寻找,如果依然找不到,就抛出ClassNotFoundException了。

为了动态加载hello.jar里面的Util类,我们需要将这个jar包放入到我们的类加载器中去,然后再获取里面的类。如下面的代码。

//位于hello.jar

packagecom.flyingzl;

publicclassUtil{

publicstaticvoidgetVersion(){

System.out.println("javaversion:"+System.getProperty("java.version"));

importjava.io.File;

importjava.lang.reflect.Method;

importjava.net.URL;

importjava.net.URLClassLoader;

publicclassMain{

publicstaticvoidmain(String[]args){

URL[]urls=newURL[]{};

MyClassLoaderclassLoader=newMyClassLoader(urls,null);

classLoader.addJar(newFile("c:/hello.jar").toURI().toURL());

Class<?>clazz=classLoader.loadClass("com.flyingzl.Util");

Methodmethod=clazz.getDeclaredMethod("getVersion");

method.invoke(null);

classLoader.close();

}catch(Exceptione){

e.printStackTrace();

staticclassMyClassLoaderextendsURLClassLoader{

publicMyClassLoader(URL[]urls){

super(urls);

publicMyClassLoader(URL[]urls,ClassLoaderparent){

super(urls,parent);

publicvoidaddJar(URLurl){

this.addURL(url);

注意:这里仅仅是为了展示如何动态加载jar包,代码写得很粗,生产代码需要有更完善的异常处理。我们只关心如何动态加载jar包即可。

动态加载jar包,需要用到java.net.URLClassLoader这个类,它可以指定一个路径将jar包或者classes文件加载到类空间。加载完毕后,直接调用loadClass就可以加载指定的类,然后通过反射生成实例或者调用方法即可。

其实,Tomcat等服务器也利用了此思路,比如每一个web应用启动时,它都会自动加载其下的lib文件夹下的jar包。

运行程序,我们就可以看到程序正常输出:

javaversion:1.7.0_03

哎,写了一堆,居然没了,太坑了,这样简单说吧,getVersion方法有段代码:Util.class.getResource("/config/version.xml"),Main创建的Classloader去加载Util类,

invokergetVersion时会找不到version.xml,尽管打包的时候和jar包放一起的路径

有谁在android上自定义过类加载器呀??

对于需要继承Activity、Service等的类,你是没有几乎去用自己的类加载器加载的,因为构造方法不是你能调用的。除非修改框架,但那样你的系统跟其他Android系统就不兼容了。对于自己有机会调用构造方法创建的对象,才有机会使用自定义的类加载器。

什么是类加载机制及虚拟机加载类的时机?

虚拟机把描述类的数据从class文件加载到内存,并对class文件的合法性进行验证,引用转换及解析,最终形成可以被虚拟机使用的Java类型,这就是虚拟机的类加载机制。

由于java的动态扩展特点(就是可以在运行期指定具体类型),所以java的类加载过程都是在程序运行期完成。

CAD如何加载自定义线?CAD如何加载自定义线形

第一步是按照线形的定义方式,制作线形文件,是以.lin结尾的文件。然后打开cad文件,加载即可。

为什么自定义类加载器

如果不牵涉到页面,就写在servlet里面,然后配置在web.xml中。tomcat容器启动的时候会自动调用你那个servlet的初始化方法。。整个类就加载了。对于需要继承activity、service等的类,你是没有几乎去用自己的类加载器加载的,因为构造方法不是你能调用的。除非修改框架,但那样你的系统跟其他android系统就不兼容了。对于自己有机会调用构造方法创建的对象,才有机会使用自定义的类加载器。

classloader的原理 有哪些类加载器 为什么要用自定义类加载器

原理之类的,你自己上网看资料吧,不是一两句话说得清的。

至于为什么用自定义类加载器,个人总结了一下可能有下面几点吧,可能不全,也请大家补充:

1. 加密:众所周知,java代码很容易被反编译,如果你需要把自己的代码进行加密,可以先将编译后的代码用某种加密算法加密,然后实现自己的类加载器,负责将这段加密后的代码还原。

2. 从非标准的来源加载代码:例如你的部分字节码是放在数据库中甚至是网络上的,就可以自己写个类加载器,从指定的来源加载类。

3. 动态创建:为了性能等等可能的理由,根据实际情况动态创建代码并执行。

4. 其他(这个理由非常给力吧^_^)比较典型的自定义classloader使用情况就是给类加密。java编译的代码可以轻易的被反编译,有些企业会给自己的类做特殊的加密,防止反编译,类加密后就不能再用java的

classloader去加载类了,这时就需要自定义classloader,再加载类的时候先解密类,然后再加载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值