来源: Thinkbase.net,
自动重新加载-自定义ClassLoader初步
自己做了一个自定义 Class-Loader 的试验, 打算做一个记录和总结, 完整的源代码可以从[ att:自动重新加载-自定义ClassLoader初步.classLoader.zip ]得到.
自定义 Class-Loader 用来做什么呢? 可以想到的有两个用途:
在 http://www.javaresearch.org 上面找到几篇关于 Class-Loader 的文章, 基本上本文的所有思路都是从这两篇文章来的:
在这两篇文章的基础上, 本文自定义了一个Class-Loader, 主要目的是:
源代码可以使用 Eclipse 直接打开, 同时下载文件中也包括 Ant 的 build.xml, 可以使用 Ant 命令建立和运行测试程序, 看到运行效果.
默认情况下
如果需要观察类自动加载的情形, 需要:
END
自己做了一个自定义 Class-Loader 的试验, 打算做一个记录和总结, 完整的源代码可以从[ att:自动重新加载-自定义ClassLoader初步.classLoader.zip ]得到.
自定义 Class-Loader 用来做什么呢? 可以想到的有两个用途:
- 用于在应用框架中自由指定应用程序类的位置(这样可以把应用程序的类和框架自身的类在位置上分开);
- 可以控制在需要的时候(比如检测到类的修改, 或者用户手工触发时)重新加载类.
在 http://www.javaresearch.org 上面找到几篇关于 Class-Loader 的文章, 基本上本文的所有思路都是从这两篇文章来的:
在这两篇文章的基础上, 本文自定义了一个Class-Loader, 主要目的是:
- 实现一个 Class-Loader, 支持从自定义的路径(包括目录和jar文件)中加载类;
- 尝试在避免重启的情况下自动重新加载修改过的类;
- 试验一种检测类文件修改的机制;
- 提供例子和测试程序, 测试 Class-Loader 的实现在发现和加载/重新加载类文件和资源文件时的行为.
源代码下载
源代码可以从[ att:自动重新加载-自定义ClassLoader初步.classLoader.zip ]下载.源代码可以使用 Eclipse 直接打开, 同时下载文件中也包括 Ant 的 build.xml, 可以使用 Ant 命令建立和运行测试程序, 看到运行效果.
如何运行
下载源代码后, 解压到某个目录, 在命令行下进入此目录, 运行ant build
即可完成编译, 然后运行
ant run
即可看到运行效果;
默认情况下
ant run
可以自动运行一遍相关的测试程序(请注意观察输出的信息), 然后测试程序会等待用户输入下一步命令, 输入 "c"+<回车> 将会重新执行一遍测试(请观察输出信息, 这次和最初启动时有一些差异), 输入 "x"+<回车> 将退出程序;
如果需要观察类自动加载的情形, 需要:
- 在未使用 "x"+<回车> 退出应用程序前, 在一个另外打开的命令行窗口中, 执行
ant refresh-1
,ant refresh-2
或者ant refresh-jar1
, 来使两个类目录和一个jar文件中class文件以及资源文件发生改变; - 在执行完上面的任意一条 ant 命令后, 回到原来的那个命令行窗口, 使用 "c"+<回车> 重新运行一遍测试, 注意在输出信息中的类文件修改检测和Class-Loader重新加载信息, 以及重新加载后运行结果的不同;
- 请注意类似"
... was created at [2005-06-26 23:30:58]
"这样的一些时间信息, 这些信息在每次类文件改变后会相应变化.
补充说明
关于源代码目录结构
- 系统中的源代码主要包括:
- boot-src
- 这是系统启动时的代码, 这些代码不是由自定义的Class-Loader加载的, 因此也不会自动加载;
- runtime-1-src
- 运行时由自定义Class-Loader加载的代码(1);
- runtime-2-src
- 运行时由自定义Class-Loader加载的代码(2);
- runtime-jar1-src
- 运行时由自定义Class-Loader加载的代码, 与上面的两个runtime不同, 这个目录下的代码在编译之后是以jar包的形式被加载到系统中的.
- boot-src
其它
- 本例子还尝试了从 jar 文件中加载 class 和 资源文件 的操作, 具体请参考相关代码;
- 在覆盖jar文件的测试例子(
ant refresh-jar1
)中, 经过多次实验发现在这种情况下, 如果直接将编译结果打包到目标jar文件, 在以URL形式加载jar包中资源的时候, 容易引起Zip操作相关的错误, 经推断可能是因为jar包在这种情况下仍然保持打开状态(可以修改, 但是无法删除); 为了解决这个问题, 尝试首先在一个临时目录中生成需要的jar包, 然后复制覆盖目标jar文件, 通过这样处理, 避免了上述的Zip操作相关错误.
END