您的位置:首页 > 其它

动态加载远程Jar的实现方式

2016-04-16 20:44 921 查看
摘要: 最近项目使用的依赖库越来越多,而且服务器已经多达150台,每次版本更新都要把程序包发布到多台服务器上面,发布较慢,所以打算把所有jar包都放到一个远程服务器上面,动态加载远程Jar文件并执行。

通常动态加载Jar文件,是手动调用UrlClassLoader去加载,然后调用loader的loadClass获取到Class的引用,之后调用反射newInstance创建一个对象实例。

这种方式写出来的代码太繁琐,并且newInstance返回的对象需要强制类型转换,并且对于IDE来说都是也是不友好的,不利于代码的批量重构。

所以这种手动加载加载Jar的方式直接放弃了。

最终的解决方案是动态设置JVM的classPath,并把classPath指定到远程的Jar包。

1.我们把UserService封装到一个Jar,然后把Jar放到Http服务器的目录。

package com.sun.bean;

public class User {

private String id;

public User(String id) {
this.id = id;
}

public void sayHello() {
System.out.println("Hello everyone, my name is "+id);
}

}

package com.sun.service;

import com.sun.bean.User;

public final class UserService {

public static User getUserById(String id) {
return new User(id);
}
}
然后编译打包成UserService.jar,并放到本地Web服务器的根目录。
2.下面我们编写使用案例,留意setClassPath方法

package com.sun.bootstrap;

import java.lang.reflect.Method;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;

import com.sun.bean.User;
import com.sun.service.UserService;

public class Bootstrap {

public final static void setClassPath(String path) {
try {
URI uri = new URI(path);
URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Method add = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class });
add.setAccessible(true);
add.invoke(classLoader, uri.toURL());
} catch (Exception exp) {
exp.printStackTrace();
}
}

public static void main(String[] args) {
Bootstrap.setClassPath("http://localhost/UserService.jar");
User jim = UserService.getUserById("JimGreen");
jim.sayHello();
}

}

从Bootstrap.java的代码中可以发现,我们直接使用new UserService,而不是通过ClassLoader.loadClass().newInstance()的方式去创建UserService对象实例。

3.编译Bootstrap类,这一步是关键,在编译时一定要指定classPath,否则编译不通过

javac -classpath /Users/M/workspace/lua/UserService.jar   com/sun/bootstrap/Bootstrap.java

最后在com/sun/bootstrap路径下生成了Bootstrap.class文件。

4.执行Bootstrap类

java com/sun/bootstrap/Bootstrap
结果打印:

Hello everyone, my name is JimGreen
总结上述的方式,
我们可以按照平常的方式写代码(区别于loadClass的方式获取Class,然后newInstance),关键点在于调用了SystemClassLoader.addURL添加类加载路径,这样JVM可以主动帮我们
动态加载远程jar包。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息