(转)自定义ClassLoader ----可以加载第三方jar包
- package com.classloader.util;
- import java.io.IOException;
- import java.net.MalformedURLException;
- import java.net.URL;
- import java.net.URLClassLoader;
- import java.net.URLStreamHandlerFactory;
- import java.security.CodeSource;
- import java.security.PermissionCollection;
- import java.util.Enumeration;
- import java.util.jar.Manifest;
- 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");
这里初始化了此类加载器所使用的类资源,配置文件等。
以下是如何加载类资源:
- Class clazz= loader.findClass("com.jvm.look.A");//加载类
以下是加载配置文件资源
- URL uuu = loader.findResource("App/config.xml");
有一点需要注意的,这个类加载器还是双亲委托机制,比如有一个类"com.annotation.table.Test"在父类加载器中如果已经加载过了,那么如果这个类在test.jar中存在,那么不会重新定义加载,而使用父类加载器加载的类,有人问了,那我如何覆盖父类加载器中定义的类。
可以进行如下操作:
- Class clazz2= loader.findClass("com.annotation.table.Test");
重新加载类,类的加载序列我在上一篇已经讲过了,不熟悉的可以看以上文章.
可能有人会问了,如果每一个类都这样,那我不崩溃了,我需要把我加载的jar覆盖父类加载器中定义的所有类.
- /**
- * 覆盖父加载器中定义的类,使用当前类加载器加载资源,那么所有的类都在此加载器中执行.
- * 这样,所有URL中的类都通过此类加载器加载,也就是说URL中的类的定义类加载器就是当前类加载器.
- * 建议:尽量不要使用这种方式覆盖父加载器定义的类.[按一种约定双亲委托机制加载]
- * (如果重载了,那么尽量使用此loader加载类,这样所有逻辑都在此ClassLoader中运行,当然还有SDK还是从双亲加载)
- * 可以在SDK中定义接口,在此JAR里面提供实现.
- */
- public void initAllJar(){
- URL[] urls = this.getURLs();
- for(URL urll:urls){
- String url = urll.getFile();
- //重新定义这个架包中的所有类.
- if(url.endsWith("jar")){
- File jarFile = getJarFile(url);
- JarFile jarFileTemp = null;
- try {
- jarFileTemp = new JarFile(jarFile);
- Enumeration<JarEntry> en = jarFileTemp.entries();
- while (en.hasMoreElements()) {
- JarEntry je = en.nextElement();
- String name = je.getName();
- if (name.endsWith(CLASS_FILE)) {
- String className = name.substring(0, name.length()
- - CLASS_FILE.length());
- findClass(pathToDot(className));
- }
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (ClassNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- /**
- * 转jar包路径和jar文件名为具体文件.
- *
- * @param root
- * @param jar
- * @return
- */
- private File getJarFile(String file) {
- if (file.startsWith(PREFIX_FILE))
- file = file.substring(PREFIX_FILE.length());
- int end = file.indexOf(JAR_URL_SEPERATOR);
- if (end != (-1))
- file = file.substring(0, end);
- return new File(file);
- }
- /**
- * 转路径为包名[/ ==> .]/[\\ ==> .]
- * @param s
- * @return
- */
- private String pathToDot(String s) {
- return s.replace('/', '.').replace('\\', '.');
- }
其实JDK中已经提供了好几个ClassLoader,大家可以扩展,比如项目中有两个架包版本,结构全部都一样,但是两个架包都必须运行。这时自定义类加载器就有用了。
转:http://a123159521.iteye.com/blog/1095264
(转)自定义ClassLoader ----可以加载第三方jar包的更多相关文章
- 27 Java动态加载第三方jar包中的类
我加载的方法是://参数fileName是jar包的路径,processorName 是业务类的包名+类名public static A load(String fileName, String pr ...
- maven加载第三方jar包
<dependency> <groupId>com.yeepay</groupId> <artifactId>yop-sdk</artifactI ...
- 自定义ClassLoader,用于加载用户JAR包
最近在考虑C/S结构程序的软件自动升级的实现方式,比如QQ.飞信等都自动升级的功能. 自动升级模块虽然还没有编码完成,但是思路还是比较清晰的. 自动升级过程中,升级文件的JAR包是专门加载到程序中去的 ...
- 加载所有jar包下指定文件
加载所有jar包下指定文件: 如spring中加载 META-INF/spring.handlers 加载 org.springframework.core.io.support.Properties ...
- Spark on Yarn运行时加载的jar包
spark on yarn运行时会加载的jar包有如下: spark-submit中指定的--jars $SPARK_HOME/jars下的jar包 yarn提供的jar包 spark-submit通 ...
- Classpath in jar关于java加载第三方jar的集中方法和详细解释。
转载地址:http://www.iteye.com/topic/332580 大家都知道一个java应用项目可以打包成一个jar,当然你必须指定一个拥有main函数的main class作为你这个ja ...
- maven加载本地jar包到repository
maven加载本地jar到repository 这是一个常见场景,此处以本地opencv jar文件导入repository为例 1.Ubuntu下 mvn install:install-file ...
- maven 手动加载第三方jar、zip包
使用maven搭建工程时,难免要加载大量的第三方的jar包.zip包比较少用,而maven的官网提供的jar往往不能满足需求,这时需要我们手动加载到我们本地或nexus私服的仓库中. 1.加载jar包 ...
- maven加载第三方jar不能加载
这个问题处于项目组,总算是解决了.下面是一些自己的做法. 1.说明介绍 公司现在用的是spring+maven,使用的公共maven库没有问题,但是想要把一些老的项目改造这种框架会出现一些问题. 因为 ...
随机推荐
- RHEL5/6/7中常用命令及命令之间的差异
System basics Task RHEL5 RHEL6 RHEL7 View subscription information /etc/sysconfig/rhn/systemid /etc/ ...
- C# 简单的统计指定几个字符组合的所有结果
比如 用 a,b,c,d 4个字符组成一个8个长度的字符串,问一共有多少可能,应该有4的8次方种,用代码简单实现 private string[] AAA() { string[] cs = { &q ...
- js实现正则判断手机号
//判断是否为手机号的正则表达式 function phoneFun(phones){ var myreg = /^[1][3,4,5,7,8,9][0-9]{9}$/; if (!myreg.tes ...
- shell脚本明文密码隐藏且加密
将密码放到文件中去,比如/root/.pass.txtpassword=`</root/.pass.txt`还怕密码泄露的话,就把pass.txt权限设置下. chattr +i /root/. ...
- 26.String类(1)
1. 下面是一个使用equals的例子: 我查看了一下源代码,string类中equals方法的源代码如下: public boolean equals(Object anObject) { if ( ...
- python模块:typing
很多人在写完代码一段时间后回过头看代码,很可能忘记了自己写的函数需要传什么参数,返回什么类型的结果,就不得不去阅读代码的具体内容,降低了阅读的速度,加上Python本身就是一门弱类型的语言,这种现象就 ...
- 零距离接触阿里云时序时空数据库TSDB
概述 最近,Amazon新推出了完全托管的时间序列数据库Timestream,可见,各大厂商对未来时间序列数据库的重视与日俱增.阿里云TSDB是阿里巴巴集团数据库事业部研发的一款高性能分布式时序时空数 ...
- HDFS(Hadoop Distributed File System)的组件架构概述
1.hadoop1.x和hadoop2.x区别 2.组件介绍 HDFS架构概述1)NameNode(nn): 存储文件的元数据,如文件名,文件目录结构,文件属性(生成时间,副本数,文件权限),以及每个 ...
- document.body / document.ducumentElement /等获取高度和宽度的区别
document.body / document.ducumentElement /等获取高度和宽度的区别 <!DOCTYPE html> <html> <head la ...
- centos7.2搭建kubernetes1.5.2+dashboard
一. 简介 近来容器对企业来说已经不是什么陌生的概念,Kubernetes作为Google开源的容器运行平台,受到了大家的热捧.搭建一套完整的kubernetes平台,也成为试用这套平台必须迈过 ...