动态加载远程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包。

你可能感兴趣的:(ClassLoader,jar,classpath,动态加载)