尝试通过自定义ClassLoader 配和 ASM实现AOP.
package com.hkliang.core.web;
public class WebClassLoader extends ClassLoader{
public WebClassLoader(){
super(WebClassLoader.class.getClassLoader());
}
public Class<?> defineClass(String name, byte[] code) throws ClassNotFoundException{
return defineClass(name, code, 0, code.length );
}
}
在Servlet中
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
WebClassLoader webClassLoader = new WebClassLoader();
String className = "com.hkliang.core.aop.asm.Test";
try {
Class test = webClassLoader.defineClass(className, PrintClass.getBytesFromBasePath(className));
ClassLoader cl = test.getClassLoader();
System.out.println( "Test is loader by " + cl);
while (cl != null ) {
cl = cl.getParent();
System.out.println(cl);
}
Test t = (Test)test.newInstance();
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
异常信息为
INFO: Server startup in 8967 ms
test is com.hkliang.core.web.WebClassLoader@5eaecb
WebappClassLoader
context:
delegate: false
repository: /WEB-INF/classes/
----------> Parent Classloader:
java.net.URLClassLoader@438d57
java.net.URLClassLoader@438d57
sun.misc.Launcher$AppClassLoader@167198e
sun.misc.Launcher$ExtClassLoader@1beea90
null
问题:Servlet中声明的Test与自定义ClassLoader加载的Test不是在同一个ClassLoader中,如何实现自定义ClassLoader通过加载 byte[]类型的字节码,并委托给父加载器进行加载呢,实现AOP的目标呢?
自定议的ClassLoader使用反射方式:
public class WebClassLoader extends ClassLoader {
public WebClassLoader() {
super(WebClassLoader.class.getClassLoader());
}
public Class<?> defineClass(String name, byte[] code)
throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
ClassLoader loader = getParent();
Class<?> cls = ClassLoader.class;
Method method = cls.getDeclaredMethod(
"defineClass", new Class[] { String.class, byte[].class,int.class, int.class });
method.setAccessible(true);
Object[] args = new Object[] {name, code, new Integer(0), new Integer(code.length) };
Class clazz = (Class<?>) method.invoke(loader, args);
try {
clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
}
return clazz;
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
return getParent().loadClass(name);
}
}
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。