深入理解Java类加载器(3)
5.2 网络类加载器
下面将通过一个网络类加载器来说明如何通过类加载器来实现组件的动态更新。即基本的场景是:Java 字节代码(.class)文件存放在服务器上,客户端通过网络的方式获取字节代码并执行。当有版本更新的时候,只需要替换掉服务器上保存的文件即可。通过类加载器可以比较简单的实现这种需求。
类 NetworkClassLoader负责通过网络下载Java类字节代码并定义出Java类。它的实现与FileSystemClassLoader类似。
package classloader; import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL; public class NetworkClassLoader extends ClassLoader { private String rootUrl; public NetworkClassLoader(String rootUrl) {
// 指定URL
this.rootUrl = rootUrl;
} // 获取类的字节码
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classData = getClassData(name);
if (classData == null) {
throw new ClassNotFoundException();
} else {
return defineClass(name, classData, 0, classData.length);
}
} private byte[] getClassData(String className) {
// 从网络上读取的类的字节
String path = classNameToPath(className);
try {
URL url = new URL(path);
InputStream ins = url.openStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bufferSize = 4096;
byte[] buffer = new byte[bufferSize];
int bytesNumRead = 0;
// 读取类文件的字节
while ((bytesNumRead = ins.read(buffer)) != -1) {
baos.write(buffer, 0, bytesNumRead);
}
return baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
return null;
} private String classNameToPath(String className) {
// 得到类文件的URL
return rootUrl + "/"
+ className.replace('.', '/') + ".class";
}
}
在通过NetworkClassLoader加载了某个版本的类之后,一般有两种做法来使用它。第一种做法是使用Java反射API。另外一种做法是使用接口。需要注意的是,并不能直接在客户端代码中引用从服务器上下载的类,因为客户端代码的类加载器找不到这些类。使用Java反射API可以直接调用Java类的方法。而使用接口的做法则是把接口的类放在客户端中,从服务器上加载实现此接口的不同版本的类。在客户端通过相同的接口来使用这些实现类。我们使用接口的方式。示例如下:
客户端接口:
package classloader;
public interface Versioned {
String getVersion();
}
package classloader;
public interface ICalculator extends Versioned {
String calculate(String expression);
}
网络上的不同版本的类:
package com.example;
import classloader.ICalculator;
public class CalculatorBasic implements ICalculator {
@Override
public String calculate(String expression) {
return expression;
}
@Override
public String getVersion() {
return "1.0";
}
}
package com.example;
import classloader.ICalculator;
public class CalculatorAdvanced implements ICalculator {
@Override
public String calculate(String expression) {
return "Result is " + expression;
}
@Override
public String getVersion() {
return "2.0";
}
}
在客户端加载网络上的类的过程:
package classloader;
public class CalculatorTest {
public static void main(String[] args) {
String url = "http://localhost:8080/ClassloaderTest/classes";
NetworkClassLoader ncl = new NetworkClassLoader(url);
String basicClassName = "com.example.CalculatorBasic";
String advancedClassName = "com.example.CalculatorAdvanced";
try {
Class<?> clazz = ncl.loadClass(basicClassName); // 加载一个版本的类
ICalculator calculator = (ICalculator) clazz.newInstance(); // 创建对象
System.out.println(calculator.getVersion());
clazz = ncl.loadClass(advancedClassName); // 加载另一个版本的类
calculator = (ICalculator) clazz.newInstance();
System.out.println(calculator.getVersion());
} catch (Exception e) {
e.printStackTrace();
}
}
}
深入理解Java类加载器(3)的更多相关文章
- 深入理解Java类加载器(ClassLoader)
深入理解Java类加载器(ClassLoader) Java学习记录--委派模型与类加载器 关于Java类加载双亲委派机制的思考(附一道面试题) 真正理解线程上下文类加载器(多案例分析) [jvm解析 ...
- 深入理解Java类加载器(ClassLoader) (转)
转自: http://blog.csdn.net/javazejian/article/details/73413292 关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Ja ...
- 深入理解Java类加载器(一):Java类加载原理解析
摘要: 每个开发人员对java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这个异常背后涉及到的是Java技术体系中的类加载机制.本文简述了JVM三种预定义类加载器,即 ...
- 深入理解Java类加载器(二):线程上下文类加载器
摘要: 博文<深入理解Java类加载器(一):Java类加载原理解析>提到的类加载器的双亲委派模型并不是一个强制性的约束模型,而是Java设计者推荐给开发者的类加载器的实现方式.在Java ...
- java笔记--理解java类加载器以及ClassLoader类
类加载器概述: java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制 ...
- 深入理解Java类加载器(1):Java类加载原理解析
1 基本信息 每个开发人员对Java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java技术体系中的类加载.Java的类加载机制是技术体系中比较核心的 ...
- 转载 深入理解java类加载器
1 基本信息 每个开发人员对java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java技术体系中的类加载.Java的类加载机制是技术体系中比较核心的 ...
- 深入理解Java类加载器(2)
1 基本信息 每个开发人员对Java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java技术体系中的类加载.Java的类加载机制是技术体系中比较核心的 ...
- 深入理解Java类加载器(1)
类加载器概述: java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制 ...
随机推荐
- Scrapy-从数据库取出IP并判断是否可用
import pymysql import requests conn = pymysql.connect(host="localhost",user="root&quo ...
- 生死系列--SongXingZhi
SongXingZhi,我上中专时的同学,任劳动委员,湖北随州人.其实在上学以及毕业后,我们俩没什么交往,也没说过几句话. 印象比较深的一次是在上什么课时,老师拖堂了 ,他直接从课桌上翻过来,从后门出 ...
- 2017-2018-2 《网络对抗技术》 20155322 第五周 Exp2 后门原理与实践
#2017-2018-2 <网络对抗技术> 20155322 第五周 Exp2 后门原理与实践 [博客目录] 1-实践目标 1.1-实践介绍 1.2-实践内容 1.3-实践要求 2-实践过 ...
- Noip前的大抱佛脚----数论
目录 数论 知识点 Exgcd 逆元 gcd 欧拉函数\(\varphi(x)\) CRT&EXCRT BSGS&EXBSGS FFT/NTT/MTT/FWT 组合公式 斯特林数 卡塔 ...
- SpringCloud-微服务配置统一管理SpringCloud Config(七)
前言:对于应用,配制文件通常是放在项目中管理的,它可能有spring.mybatis.log等等各种各样的配置文件和属性文件,另外你还可能有开发环境.测试环境.生产环境等,这样的话就得一式三份,若是传 ...
- window.location.hash 页面跳转,精确定位,实例展示:
window.location.hash 页面跳转,精确定位,实例展示: (1).index.phtml,页面用于传参 <script id="bb_list_template&quo ...
- python中while循环和for循环的定义和详细的使用方法
1. 循环的定义,反复做某事,具有明确的开始和结束. 2. 在Python中循环有while和for两种方式: While循环:1) 语法结构 >>> while 条件: ... ...
- 【日常训练】Help Victoria the Wise(Codeforces 99C)
题意与分析 这题意思是这样的:在正方体的六面镶嵌给定颜色的宝石(相同颜色不区分),然后问最多有几种彼此不等价(即各种旋转过后看起来一致)的方案. 其实可以乱搞,因为范围只有720.求出全排列,然后每个 ...
- python数据分析的工具环境
python做数据分析的优势: 拥有大量的库为数据分析和处理提供了完整的工具链 随着库还在不断的增加的同时, 算法的实现也更加的创新.Numpy, matplotlib, scipy,scikit-l ...
- Scrapy爬取携程桂林问答
guilin.sql: CREATE TABLE `guilin_ask` ( `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键', `question ...