jdk动态代理实现原理(二)
下面对jdk动态代理实现进一步进行优化,考虑方法有返回值的情况,最终的实现类似于源码。
1.接口
interface Foo{void foo();int bar();}interface InvocationHandler{Object invoke(Object proxy,Method method, Object[] args) throws Throwable;}Foo接口的产生变化,bar方法返回值为int。InvocationHandler接口的invoke方法增加参数Object proxy,可以传入代理对象。
2.目标类
static class Target implements Foo{@Overridepublic void foo() {System.out.println("target foo");}@Overridepublic int bar() {System.out.println("target bar");return 1;}}重写bar方法要有返回值。
3.代理类
public class $Proxy0 implements Foo {private InvocationHandler h;public $Proxy0(InvocationHandler h){this.h = h;}@Overridepublic void foo() {try {h.invoke(this,foo,new Object[0]);}catch (RuntimeException | Error e){throw e;}catch (Throwable e) {throw new UndeclaredThrowableException(e);}}@Overridepublic int bar() {try {Object invoke = h.invoke(this, bar, new Object[0]);return (int)invoke;}catch (RuntimeException | Error e){throw e;}catch (Throwable e) {throw new UndeclaredThrowableException(e);}}static Method foo;static Method bar;static {try {foo = Foo.class.getMethod("foo");bar = Foo.class.getMethod("bar");} catch (NoSuchMethodException e) {throw new NoSuchMethodError(e.getMessage());}}
}把方法对象的获取抽象成静态代码块,同时进行更精确的异常捕获。
4.主类
public static void main(String[] params) {Foo proxy = new $Proxy0(new InvocationHandler() {@Overridepublic Object invoke(Object proxy,Method method, Object[] args) throws Throwable {//功能增强System.out.println("before....");//调用目标return method.invoke(new Target(),args);}});proxy.foo();proxy.bar();}结果:

