反射调用异常InvocationTargetException和代理类抛出异常
2017-11-15 01:29 Loull 阅读(1722) 评论(0) 收藏 举报反射调用方法,如果方法抛出异常,会被包装成InvocationTargetException。
如果反射对象被代理了,在代理类中抛出异常,不会被包装成InvocationTargetException。
package com.loull.test.aop; public interface Person { void sayHello(); }
package com.loull.test.aop; public class PersonImpl implements Person { @Override public void sayHello() { throw new RuntimeException("sayHello Exp"); } }
package com.loull.test.aop; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class ProxyExpTest { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException { Class<?> personImplClz = Class.forName("com.loull.test.aop.PersonImpl"); Method method = personImplClz.getMethod("sayHello"); try { method.invoke(personImplClz.newInstance()); } catch (Exception e) { e.printStackTrace(); } Object person = personImplClz.newInstance(); Person proxyPersion = (Person) Proxy.newProxyInstance(personImplClz.getClassLoader(), person.getClass().getInterfaces(), new MyInvocationHandler(person, true)); try { proxyPersion.sayHello(); } catch (Throwable e) { e.printStackTrace(); } System.out.println("cglib"); MyCglibProxy cglibProxy = new MyCglibProxy(); Person cglibPerson = (Person) cglibProxy.getInstance(personImplClz.newInstance(), true); try { cglibPerson.sayHello(); } catch (Throwable e) { e.printStackTrace(); } System.out.println("cglib end"); } static class MyCglibProxy implements MethodInterceptor { private Object target; private boolean exp; public Object getInstance(Object target, boolean exp) { this.target = target; this.exp = exp; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); // enhancer.setCallback(this); // return enhancer.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("cglib_before invoke"); if (exp) { throw new OutOfMemoryError("proxy exp cglib"); } Object result = proxy.invokeSuper(obj, args); System.out.println("cglib_after invoke"); return result; } } static class MyInvocationHandler implements InvocationHandler { private Object target; private boolean exp; public MyInvocationHandler(Object target, boolean exp) { this.target = target; this.exp = exp; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before invoke"); if (exp) { throw new OutOfMemoryError("proxy exp"); } Object result = method.invoke(target, args); System.out.println("after invoke"); return result; } } }
输出:
java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.alipay.test.aop.ProxyExpTest.main(ProxyExpTest.java:20) Caused by: java.lang.RuntimeException: sayHello Exp at com.alipay.test.aop.PersonImpl.sayHello(PersonImpl.java:7) ... 5 more java.lang.OutOfMemoryError: proxy exp at com.alipay.test.aop.ProxyExpTest$MyInvocationHandler.invoke(ProxyExpTest.java:92) at com.sun.proxy.$Proxy0.sayHello(Unknown Source) at com.alipay.test.aop.ProxyExpTest.main(ProxyExpTest.java:29) before invoke cglib cglib_before invoke java.lang.OutOfMemoryError: proxy exp cglib at com.alipay.test.aop.ProxyExpTest$MyCglibProxy.intercept(ProxyExpTest.java:68) at com.alipay.test.aop.PersonImpl$$EnhancerByCGLIB$$9174c686.sayHello(<generated>) at com.alipay.test.aop.ProxyExpTest.main(ProxyExpTest.java:38) cglib end