详解java动态代理的2种实现方式
程序员文章站
2024-03-09 15:33:29
java的动态代理在接java的api上有说明,这里就不写了。我理解的代理:
对特定接口中特定方法的功能进行扩展,这就是代理。代理是通过代理实例关联的调用处理程序对象调用...
java的动态代理在接java的api上有说明,这里就不写了。我理解的代理:
对特定接口中特定方法的功能进行扩展,这就是代理。代理是通过代理实例关联的调用处理程序对象调用方法。
下面通过一个例子看一下:
接口:
public interface num { void show(); int getnum(); int getproduct(int x); }
实现类:
public class mynum implements num { @override public int getnum() { return 3; } @override public int getproduct(int x) { return x; } @override public void show() { system.out.println("底层方法打印数字99"); } }
先看一下method中的invoke方法在api中是怎么描述的
就是说调用处理程序对接口的实现类对象调用method对象表示的底层方法。
第一种实现代理的方式:
public class numproxy { private object num; //通过构造方法构造接口的实现类对象 public numproxy(object num) { this.num = num; } public object getnumbyproxy(){ object numproxy = proxy.newproxyinstance(num.getclass().getclassloader(), new class[]{num.class}, new invocationhandler() { /** * method: 对应于在代理实例上调用的接口方法的 method 实例。我理解的就是被代理的真实方法实例 * args: 我理解的是真实方法的参数数组 */ @override public object invoke(object proxy, method method, object[] args) throws throwable { object obj = null; system.out.println("在方法之前开始记录"); string methodname = method.getname(); if("getproduct".equals(methodname)){ obj = method.invoke(num, args); obj = (integer) obj * 2; system.out.println("proxy: getproduct()结束"); } else if("show".equals(methodname)){ obj = method.invoke(num, args); system.out.println("proxy: show()结束"); } return obj; } }); return numproxy; } }
第二种实现代理的方式:通过实现invocationhandler接口
public class numproxyimpl implements invocationhandler { //这里我把接口类型具体化了, 没有写成object private num num; public numproxyimpl(num num){ this.num = num; } @override public object invoke(object proxy, method method, object[] args) throws throwable { object obj = null; string methodname = method.getname(); if("getproduct".equals(methodname)){ system.out.println("proxy: getproduct()开始"); obj = method.invoke(num, args); obj = (integer) obj * 2; system.out.println("proxy: getproduct()结束"); }else if("show".equals(methodname)){ system.out.println("proxy: show()开始"); obj = method.invoke(num, args); system.out.println("proxy: show()结束"); } return obj; } }
测试代码:
public class testnum { public static void main(string[] args) { //两种方式一起测试 numproxy np = new numproxy(new mynum()); num numproxy = (num) np.getnumbyproxy(); int x = numproxy.getproduct(2); system.out.println(x); numproxy.show(); system.out.println("----------------"); numproxyimpl npi = new numproxyimpl(new mynum()); num numpro = (num) proxy.newproxyinstance(num.class.getclassloader(), new class[]{num.class}, npi); int n = numpro.getproduct(3); system.out.println(n); numpro.show(); } }
控制台结果:
第二种方式有点小疑惑,不知道大家有没有,那就是并没有显示的调用numproxyimpl中的invoke方法,可是却执行了,嗯嗯,这个自己下去看一下啊
不想麻烦的只需要记住就行了。
比如编码的处理就可以用到代理,下次写个例子。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。