动态代理 Proxy InvocationHandler
来源:互联网 发布:淘宝助理csv文件制作 编辑:程序博客网 时间:2024/05/17 07:26
动态代理一般用于在执行实例对象的基础上,增加一些扩展的功能,并且每个实例对象都会动态获取对象的方法
在使用动态代理有几个前提条件, 一个是对应的实例对象,一个是扩展功能,而扩展功能是通过接口才能实现扩展,所以代理我的理解就是在于扩展功能的定义,即接口的定义,而实例对象就是调用对应的方法,而这个方法动态的,通过反射获取实例对象的方法
备注:一般动态代理代码都是作为一个工具类使用,例如:Retrofit网络请求框架 有使用动态代理
1、定义扩展功能的接口
public interface IAdvice {void beforeMethod(Method method);void afterMethod(Method method);}
2、定义扩展功能的对象
public class AdviceImpl implements IAdvice {Long beginTime=(long) 0;Long endTime=(long) 0;@Overridepublic void beforeMethod(Method method) {// TODO Auto-generated method stubbeginTime=System.currentTimeMillis();System.out.println("实例方法1");}@Overridepublic void afterMethod(Method method) {// TODO Auto-generated method stub endTime=System.currentTimeMillis(); System.out.println("实例方法2"); System.out.println("方法名称"+method.getName()+"run time of "+(endTime-beginTime));}}
3、定义动态代理的方法
/*将目标类实例对象作为参数注入,供InvocationHandler调用; *将代理类要实现的扩展功能抽象成一个接口,并把对象传入 *InvocationHandler实现类中调用对象的方法,就相当于执行了外界提供的扩展功能 */<span style="color:#ff0000;">//target是实例对象,方法内的Method是实例对象调用的方法,而advice是扩展功能提供的实例对象</span>private static Object getProxy(final Object target, final IAdvice advice) {Object obj = Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method,Object[] args) throws Throwable {advice.beforeMethod(method);System.out.println("动态代理获取的方法名称=" + method.getName()+" "+target.toString());//<span style="color:#ff0000;">方法反射返回的结果是resval args 是实例对象方法内的参数,注意如果使用for循环,那么如果调用方法为空, 那么报空指针错误</span>Object retVal = method.invoke(target, args);System.out.println("反射内容="+retVal);advice.afterMethod(method);return retVal; <span style="color:#ff0000;">//除非实例对象调用的方法没有返回值(方法上没有返回值时用void),可以返回nul,否则报错</span>}});return obj;}}4、调用动态代理方法
public static void main(String[] args) {// TODO Auto-generated method stubArrayList<String> target = new ArrayList<String>();target.add("aaa");AdviceImpl impl = new AdviceImpl();//方法获取的一个是代理,一个是target对象通过反射获取的方法及方法返回的接口@SuppressWarnings("unchecked")Collection<String> proxy3 = (Collection<String>) getProxy(target,impl);proxy3.add("sss");打印日志如下;
实例方法1动态代理获取的方法名称=add [aaa]参数==sss反射内容=true //方法返回的值 ,因为方法是boolean,结果是true实例方法2方法名称addrun time of 0
5、调用动态代理方法
public static void main(String[] args) {// TODO Auto-generated method stubArrayList<String> target = new ArrayList<String>();target.add("aaa");AdviceImpl impl = new AdviceImpl();//方法获取的一个是代理,一个是target对象通过反射获取的方法及方法返回的接口@SuppressWarnings("unchecked")Collection<String> proxy3 = (Collection<String>) getProxy(target,impl);proxy3.add("sss");Object retVal = (Object) proxy3.add("gfdh");System.out.println("结果=" + retVal);
实例方法1动态代理获取的方法名称=add [aaa]参数==sss反射内容=true实例方法2方法名称addrun time of 0实例方法1动态代理获取的方法名称=add [aaa, sss]参数==gfdh反射内容=true实例方法2方法名称addrun time of 0结果=true
6、调用动态代理方法
public static void main(String[] args) {// TODO Auto-generated method stubArrayList<String> target = new ArrayList<String>();target.add("aaa");AdviceImpl impl = new AdviceImpl();//方法获取的一个是代理,一个是target对象通过反射获取的方法及方法返回的接口@SuppressWarnings("unchecked")Collection<String> proxy3 = (Collection<String>) getProxy(target,impl);//proxy3.add("sss");//Object retVal = (Object) proxy3.add("gfdh");//System.out.println("结果=" + retVal);System.out.println(proxy3.size());
备注 target调用的size()方法返回的是整形类型
结果日志如下:
实例方法1动态代理获取的方法名称=size [aaa]反射内容=1实例方法2方法名称sizerun time of 01
1 0
- 动态代理 Proxy InvocationHandler
- 动态代理proxy ,InvocationHandler
- 动态代理 Proxy InvocationHandler
- java动态代理-InvocationHandler Proxy
- Java动态代理InvocationHandler+Proxy
- InvocationHandler,proxy之动态代理
- 动态代理 Proxy InvocationHandler学习
- 动态代理 Proxy, InvocationHandler 用法
- JDK动态代理proxy,InvocationHandler
- 动态代理 Proxy InvocationHandler学习
- java 动态代理学习(Proxy,InvocationHandler)
- java 动态代理深度学习(Proxy,InvocationHandler)
- java 动态代理学习(Proxy,InvocationHandler)
- jdk proxy invocationhandler (jdk动态代理)
- JAVA动态代理实现 Proxy InvocationHandler
- JAVA JDK 动态代理 proxy invocationHandler
- java 动态代理深度学习(Proxy,InvocationHandler)
- Java 动态代理(proxy、invocationHandler)
- android:windowSoftInputMode属性详解
- 新浪分享跳转网页返回/关闭网页按钮不显示的解决
- Unity3d暴风魔镜发布ios问题记录
- BZOJ4205卡牌配对
- I/O流操作
- 动态代理 Proxy InvocationHandler
- android中popupwindow弹出后,屏幕背景变成半透明
- Context.getExternalFilesDir()和Context.getExternalCacheDir()方法
- C++PRIMER 学习笔记
- 关于makefile
- GDI+双缓冲
- Android实现读取相机(相册)图片并进行剪裁
- JFinal学习--04Handler
- css3之渐变