一、前言
关于jasper的jasper-compiler源码中org.apache.jasper.servlet.JasperLoader类,继承java.net.URLClassLoader自定网络类加载器,另外这边基于抽象类ClassLoader自定义MyClassLoader类加载器实现示例,具体参见如下源码说明部分。
二、源码说明
1.源码包中的JasperLoader类
package org.apache.jasper.servlet;@b@@b@import java.io.IOException;@b@import java.io.InputStream;@b@import java.net.URL;@b@import java.net.URLClassLoader;@b@import java.security.CodeSource;@b@import java.security.PermissionCollection;@b@@b@public class JasperLoader extends URLClassLoader@b@{@b@ private PermissionCollection permissionCollection;@b@ private CodeSource codeSource;@b@ private String className;@b@ private ClassLoader parent;@b@ private SecurityManager securityManager;@b@@b@ public JasperLoader(URL[] urls, ClassLoader parent, PermissionCollection permissionCollection, CodeSource codeSource)@b@ {@b@ super(urls, parent);@b@ this.permissionCollection = permissionCollection;@b@ this.codeSource = codeSource;@b@ this.parent = parent;@b@ this.securityManager = System.getSecurityManager();@b@ }@b@@b@ public Class loadClass(String name)@b@ throws ClassNotFoundException@b@ {@b@ return loadClass(name, false);@b@ }@b@@b@ public Class loadClass(String name, boolean resolve)@b@ throws ClassNotFoundException@b@ {@b@ Class clazz = null;@b@@b@ clazz = findLoadedClass(name);@b@ if (clazz != null) {@b@ if (resolve)@b@ resolveClass(clazz);@b@ return clazz;@b@ }@b@@b@ if (this.securityManager != null) {@b@ int dot = name.lastIndexOf(46);@b@ if (dot >= 0)@b@ try@b@ {@b@ if (!("org.apache.jasper.runtime".equalsIgnoreCase(name.substring(0, dot))))@b@ this.securityManager.checkPackageAccess(name.substring(0, dot));@b@ }@b@ catch (SecurityException se) {@b@ String error = "Security Violation, attempt to use Restricted Class: " + name;@b@@b@ se.printStackTrace();@b@ throw new ClassNotFoundException(error);@b@ }@b@@b@ }@b@@b@ if (!(name.startsWith("org.apache.jsp")))@b@ {@b@ clazz = this.parent.loadClass(name);@b@ if (resolve)@b@ resolveClass(clazz);@b@ return clazz;@b@ }@b@@b@ return findClass(name);@b@ }@b@@b@ public InputStream getResourceAsStream(String name)@b@ {@b@ InputStream is = this.parent.getResourceAsStream(name);@b@ if (is == null) {@b@ URL url = findResource(name);@b@ if (url != null)@b@ try {@b@ is = url.openStream();@b@ } catch (IOException e) {@b@ is = null;@b@ }@b@ }@b@@b@ return is;@b@ }@b@@b@ public final PermissionCollection getPermissions(CodeSource codeSource)@b@ {@b@ return this.permissionCollection;@b@ }@b@}
2.自定义MyClassLoader类
package test;@b@@b@import java.io.ByteArrayOutputStream;@b@import java.io.File;@b@import java.io.FileInputStream;@b@import java.io.FileNotFoundException;@b@import java.io.IOException;@b@import java.io.InputStream;@b@@b@public class MyClassLoader extends ClassLoader{@b@@b@ private String classpath;@b@ @b@ public MyClassLoader(String classpath) {@b@ @b@ this.classpath = classpath;@b@ }@b@@b@ @Override@b@ protected Class<?> findClass(String name) throws ClassNotFoundException {@b@ try {@b@ byte [] classDate=getDate(name);@b@ if(classDate==null){@b@ } else{@b@ //defineClass方法将字节码转化为类@b@ return defineClass(name,classDate,0,classDate.length);@b@ }@b@ @b@ } catch (IOException e) {@b@ e.printStackTrace();@b@ }@b@ return super.findClass(name);@b@ }@b@ //返回类的字节码@b@ private byte[] getDate(String className) throws IOException{@b@ InputStream in = null;@b@ ByteArrayOutputStream out = null;@b@ String path=classpath + File.separatorChar +className.replace('.',File.separatorChar)+".class";@b@ try {@b@ in=new FileInputStream(path);@b@ out=new ByteArrayOutputStream();@b@ byte[] buffer=new byte[2048];@b@ int len=0;@b@ while((len=in.read(buffer))!=-1){@b@ out.write(buffer,0,len);@b@ }@b@ return out.toByteArray();@b@ } @b@ catch (FileNotFoundException e) {@b@ e.printStackTrace();@b@ }@b@ finally{@b@ in.close();@b@ out.close();@b@ }@b@ return null;@b@ }@b@}