上一篇文章我们详细的讲解了创建代理类的调用处理程序(实现InvocationHandler接口的类),获得代理对象的Proxy类,但是就发现InvocationHandler中的invoke方法中的第一个参数proxy好像从来没有用过,所以就开始在网上查询proxy的用途,最后在国外的网站上找到了不错的讲解stackoverflow.com,下面就根据自己的学习心得,讲解一下proxy。
1.讲解前我们先列一下我们要说明的问题
- proxy代表什么意思
- proxy参数怎么用及什么时候用
- proxy参数运行时的类型是什么
- 为什么不用this代替proxy
2.proxy代表什么意思
proxy是真实对象的真实代理对象,invoke方法可以返回调用代理对象方法的返回结果,也可以返回对象的真实代理对象(com.sun.proxy.$Proxy0)。
3.proxy参数怎么用及什么时候用
proxy参数是invoke方法的第一个参数,通常情况下我们都是返回真实对象方法的返回结果,但是我们也可以将proxy返回,proxy是真实对象的真实代理对象,我们可以通过这个返回对象对真实的对象做各种各样的操作。
- 创建一个接口People,包含一个work方法,方法的返回对象是它本身
package com.test.Application; public interface People { public People work(String workName); public String time(); }
- 创建一个接口People的实现类Student
package com.test.Application; public class Student implements People{
@Override public People work(String workName) { System.out.println("工作内容是"+workName); return this; } @Override public String time() { return "2018-06-12"; } }
- 创建一个代理类的调用处理程序WorkHandler
package com.test.Application; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class WorkHandler implements InvocationHandler{
private Object obj; public WorkHandler(Object obj) { this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before 动态代理..."); System.out.println(proxy.getClass().getName()); System.out.println(this.obj.getClass().getName()); if(method.getName().equals("work")) { method.invoke(this.obj, args); System.out.println("after 动态代理..."); return proxy; } else { System.out.println("after 动态代理..."); return method.invoke(this.obj, args); } } }
我们可以看到上面的代理类调用处理程序打印了proxy参数对象,并且返回了proxy对象。
- 客户端实例创建代理对象并输出结果
package com.test.Application; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { People people = new Student(); InvocationHandler handler = new WorkHandler(people); People proxy = (People)Proxy.newProxyInstance(people.getClass().getClassLoader(), people.getClass().getInterfaces(), handler); People p = proxy.work("写代码").work("开会").work("上课"); System.out.println("打印返回的对象"); System.out.println(p.getClass()); String time = proxy.time(); System.out.println(time); } }
运行结果:
after 动态代理... before 动态代理... com.sun.proxy.$Proxy0 com.test.Application.Student 工作内容是上课 after 动态代理... 打印返回的对象 class com.sun.proxy.$Proxy0 class com.sun.proxy.$Proxy0 before 动态代理... com.sun.proxy.$Proxy0 com.test.Application.Student after 动态代理... 2018-06-12
我们可以看到WorkHandler代理调用处理程序打印proxy参数输出的结果是com.sun.proxy.$Proxy0,这也说明proxy参数是代理类的真实代理对象;Proxy类生成的代理对象可以调用work方法并且返回真实的代理对象,也可以通过反射来对真实的代理对象进行操作。
4.proxy参数运行时的类型是什么
上面我们已经打印出了proxy的类型是:com.sun.proxy.$Proxy0真实的代理对象
5.为什么不用this替代
因为this代表的是InvocationHandler接口实现类本身,并不是真实的代理对象。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/214805.html原文链接:https://javaforall.net
