自定义ClassLoader在 Web环境下的问题
尝试通过自定义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 七月 13, 2013 1:17:37 上午 org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet [com.hkliang.project.controller.ProjectController] in context with path [] threw exception java.lang.ClassCastException: com.hkliang.core.aop.asm.Test cannot be cast to com.hkliang.core.aop.asm.Test at com.hkliang.project.controller.ProjectController.doGet(ProjectController.java:47) at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) at javax.servlet.http.HttpServlet.service(HttpServlet.java:728) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:83) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:223) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:107) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:75) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:933) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:90) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:493) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:986) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625) at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1584) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1543) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Threakkdd.run(Thread.java:722)问题:Servlet中声明的Test与自定义ClassLoader加载的Test不是在同一个ClassLoader中,如何实现自定义ClassLoader通过加载 byte[]类型的字节码,并委托给父加载器进行加载呢,实现AOP的目标呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
恩,恭喜! 这个问题告诉我们,有时候问题的原因也许真的不在我们这里
自己解决了,看一下 ClassLoader的源码:
defineClass 为 final,就是子类不能重写
自定议的ClassLoader使用反射方式:
就实现了,有了这个基础 配合使用Classworing工具箱(我尝试使用的是ASM)即可以开发 AOP 、IOC框架了
@陈老师apusic
要沉吗。。。
有下上及关系呀,我自定义的WebClassLoader的parent是Tomcat的WebappClassLoade
两个没有上下级关系的不同的classLoader之间没法通用class的实例。即使有上下级关系的classloader上级也是没法访问下级。
没用过asm对它内部怎么创建类实例不清楚,不过看起来跟当前servlet中使用的classloader应该是不同的,甚至有可能级别也不同。
自己顶一下,怎么没有加答,指点一二,是思路有问题吗?