java代码实现利用 classloader 动态加载 jar包、文件夹到classpath中
在项目中实现了一个工具(独立运行的Java工程,打成jar包后 通过 java -jar **.jar 执行的。),该工具通过配置能够实现一些业务功能,
并且该工具提供了接口与抽象类,供其他人扩展它的功能。
这就涉及到一个问题:别人在扩展它的时候,需要引入一些jar或者配置文件,本来工具依赖的jar和配置文件都记录在manifest文件中了,
不可能别人加了jar包和配置文件就要修改manifest文件的。
所以我为工具提供了另外一个入口,通过 该通过的配置文件 进行配置 路径,由于考虑到扩展的人可能多人或者多组,所以配置文件如下定义:
以ext_classpath开头的,诸如 ext_classpath_biz1等对应的路径均被加入到classpath中。
以ext_resourcepath开头的,诸如 ext_resourcepath_biz1等对应的路径均被加入classpath中。
代码实现如下:
package?com.bz.utils;
import?java.io.File;
import?java.lang.reflect.Method;
import?java.net.URL;
import?java.net.URLClassLoader;
import?java.util.List;
/**?*//**
?*?根据properties中配置的路径把jar和配置文件加载到classpath中。
?*?@author?jnbzwm
?*
?*/
public?final?class?ExtClasspathLoader?
{
????/**?*//**?URLClassLoader的addURL方法?*/
????private?static?Method?addURL?=?initAddMethod();
????private?static?URLClassLoader?classloader?=?(URLClassLoader)?ClassLoader.getSystemClassLoader();
????/**?*//**
?????*?初始化addUrl?方法.
?????*?@return?可访问addUrl方法的Method对象
?????*/
????private?static?Method?initAddMethod()?
{
????????try?
{
????????????Method?add?=?URLClassLoader.class.getDeclaredMethod("addURL",?new?Class[]?
{?URL.class?});
????????????add.setAccessible(true);
????????????return?add;
????????}
????????catch?(Exception?e)?
{
????????????throw?new?RuntimeException(e);
????????}
????}
????/**?*//**
?????*?加载jar?classpath。
?????*/
????public?static?void?loadClasspath()?
{
????????List<String>?files?=?getJarFiles();
????????for?(String?f?:?files)?
{
????????????loadClasspath(f);
????????}
????????List<String>?resFiles?=?getResFiles();
????????for?(String?r?:?resFiles)?
{
????????????loadResourceDir(r);
????????}
????}
????private?static?void?loadClasspath(String?filepath)?
{
????????File?file?=?new?File(filepath);
????????loopFiles(file);
????}
????private?static?void?loadResourceDir(String?filepath)?
{
????????File?file?=?new?File(filepath);
????????loopDirs(file);
????}
????/**?*//**????
?????*?循环遍历目录,找出所有的资源路径。
?????*?@param?file?当前遍历文件
?????*/
????private?static?void?loopDirs(File?file)?
{
????????//?资源文件只加载路径
????????if?(file.isDirectory())?
{
????????????addURL(file);
????????????File[]?tmps?=?file.listFiles();
????????????for?(File?tmp?:?tmps)?
{
????????????????loopDirs(tmp);
????????????}
????????}
????}
????/**?*//**????
?????*?循环遍历目录,找出所有的jar包。
?????*?@param?file?当前遍历文件
?????*/
????private?static?void?loopFiles(File?file)?
{
????????if?(file.isDirectory())?
{
????????????File[]?tmps?=?file.listFiles();
????????????for?(File?tmp?:?tmps)?
{
????????????????loopFiles(tmp);
????????????}
????????}
????????else?
{
????????????if?(file.getAbsolutePath().endsWith(".jar")?||?file.getAbsolutePath().endsWith(".zip"))?
{
????????????????addURL(file);
????????????}
????????}
????}
????/**?*//**
?????*?通过filepath加载文件到classpath。
?????*?@param?filePath?文件路径
?????*?@return?URL
?????*?@throws?Exception?异常
?????*/
????private?static?void?addURL(File?file)?
{
????????try?
{
????????????addURL.invoke(classloader,?new?Object[]?
{?file.toURI().toURL()?});
????????}
????????catch?(Exception?e)?
{
????????}
????}
????/**?*//**
?????*?从配置文件中得到配置的需要加载到classpath里的路径集合。
?????*?@return
?????*/
????private?static?List<String>?getJarFiles()?
{
????????//?TODO?从properties文件中读取配置信息略
????????return?null;
????}
????/**?*//**
?????*?从配置文件中得到配置的需要加载classpath里的资源路径集合
?????*?@return
?????*/
????private?static?List<String>?getResFiles()?
{
????????//TODO?从properties文件中读取配置信息略
????????return?null;
????}
????public?static?void?main(String[]?args)?
{
????????ExtClasspathLoader.loadClasspath();
????}
}