public class MyClassLoader extends ClassLoader {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
String path = null;
String[] names = null;
try {
path = super.getSystemResource("").getPath();
names = name.split("/");
FileUtils.copyFile(new File(name), new File(path+"/"+(getPkgname()+"\\.").replaceAll("\\.", "/")+names[names.length-1]));
} catch (IOException e) {
e.printStackTrace();
}
String classname = getPkgname()+"."+names[names.length-1].split("\\.")[0];
return super.getSystemClassLoader().loadClass(classname);
}
private String pkgname;
public String getPkgname() {
return pkgname;
}
public void setPkgname(String pkgname) {
this.pkgname = pkgname;
}
}
public static void main(String[] args) throws SQLException {
try {
MyClassLoader my = new MyClassLoader();
my.setPkgname("test");
Class c = my.findClass("D:/Test2.class");
Object o = c.newInstance();
Method[] methods = c.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
System.out.println(methods[i].getName());
methods[i].invoke(o, null);
}
} catch (Exception e) {
e.printStackTrace();
}
package test;
public class Test2 {
public void printa(){
System.out.println("xixi");
}
}
以上分别为自定义类,测试运行类和被加载类。
代码很简单,现在问题是类似这种加载classpath外的绝对路径的类java本身的ClassLoader没有这样的方法吗?然后我这样自定义的Classloader怎么在加载时启动?
继承一下URLClassLoader,之后这个类就只会加载你指定的url里面的jar包,在应用启动时候加载可以考试试试Thread.setCurrentTreadClassloader(你的classloader实例)
public class NetworkClassLoader extends URLClassLoader {
String baseUrl;
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
public NetworkClassLoader(){
this(new URL[]{});
}
/**
* URL 以'/'结尾的为目录
* 否则为jar包
* 未指定其父类加载器为系统类加载器
* @param urls
*/
public NetworkClassLoader(URL[] urls) {
super(urls);
}
/**
* 同上,指定classLoader
* @param urls
* @param parent
*/
public NetworkClassLoader(URL[] urls, ClassLoader parent) {
super(urls,parent);
}
/**
* 同上,URL工厂处理器
* @param urls
* @param parent
* @param factory
*/
public NetworkClassLoader(URL[] urls, ClassLoader parent,
URLStreamHandlerFactory factory) {
super(urls,parent,factory);
}
/**
* [添加baseUrl]
* @param url
*/
public void addURL(String url){
URL uurl=null;
try {
uurl = new URL(baseUrl+url);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
addURL(uurl);
}
/**
* 添加url[添加baseUrl]
*/
protected void addURL(URL url) {
super.addURL(url);
}
/**
* 返回urls
*/
public URL[] getURLs() {
return super.getURLs();
}
/**
* 查找类对象
* 从以上的URLS中查找加载当前类对象[会打开所有的jars去查找指定的类]
* (可以通过调用findClass来得到以上URL加载包中的类)
*/
protected Class<?> findClass(String name) throws ClassNotFoundException {
return super.findClass(name);
}
/**
* defineClass SecureClassLoader定义为最终方法,不允许更改.
* 在使用这个类对象前,必须先resolved(解析)
*/
/**
* 查找资源[自定义相对URL查找路径]
* 从以上的URLS中查找当前名称的资源
* 这个必须重写,因为是public 哈哈
*/
public URL findResource(String name) {
URL url = null;
try {
url = new URL(baseUrl+name);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return url;
}
/**
* 查找资源列表[URL查找路径]
*/
public Enumeration<URL> findResources(String name) throws IOException {
return super.findResources(name);
}
/**
* 在当前的ClassLoader中,定义一个新的Package,Package的属性由Manifest指定.这个包的源文件
*/
protected Package definePackage(String name, Manifest man, URL url)
throws IllegalArgumentException {
return super.definePackage(name, man, url);
}
/**
* 加载路径权限
*/
protected PermissionCollection getPermissions(CodeSource codesource) {
return super.getPermissions(codesource);
}
}
以下是用法:
NetworkClassLoader loader = new NetworkClassLoader();
loader.setBaseUrl("file:///F:\\框架\\maven\\app\\jms\\src\\main\\webapp\\modules\\");
loader.addURL("App/lib/test.jar");
loader.addURL("App/lib/test1.jar");
loader.addURL("App/template/view.vm");
loader.addURL("App/config.xml");
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。