JAVA反射(三)之动态代理

来源:互联网 发布:淘宝招聘在家工作 编辑:程序博客网 时间:2024/05/21 17:48

什么是动态代理

我所理解的动态代理是:在程序运行过程中,在内存中动态委托一个代理对象,来执行目标对象的方法,并且可以增强目标方法;

为什么要用动态代理

为什么要用动态代理:Java属于静态语言,所以在编译之后不能对类中的方法和属性修改,而利用动态代理可以在程序运行中可以增强某些目标对象的方法,以及实现一些过滤功能;

Proxy的获取以及参数的含义

java.lang.reflect.Proxy 类:可以看出Proxy对象在reflect包下,所以,肯定和反射有关系

用Proxy获取动态代理对象

Object objProxy = Proxy.newProxyInstance(loader,//目标对象的类加载器interfaces,//与目标对象共同实现的接口 h//InvocationHandler接口,或者InvocationHandler的实现类,用于实现代理,下面详细讲 );

InvocationHandler接口
每个代理实例都有一个关联的调用处理程序。
*在代理实例上调用方法时,该方法
*调用被编码并分派到{@code invoke}
*其调用处理程序的方法。
此接口只有一个方法

 public Object invoke(//代理该方法被调用的代理实例 Object proxy, //代理对象 Method method, //目标方法的字节码对象 Object[] args//目标方法的参数列表 );

实现动态代理的步骤

1.获取动态代理

Object objProxy = Proxy.newProxyInstance(classLoder,interfaces,h);

2.用代理对象操作目标对象的方法

objProxy .method();

用一个demo来实现步骤

总体的视图

package com.tangbaobao.reflect;/** * @author 唐学俊 * @version 创建时间:2017年11月17日 下午3:14:42 * 共有接口 */public interface TargetInterface {    public void method1();    public String method2();    public int method3(int a);}
package com.tangbaobao.reflect;/*** @author 唐学俊* @version 创建时间:2017年11月17日 下午3:15:25* 目标对象实现类*/public class Target implements TargetInterface{    @Override    public void method1() {        System.out.println("method1 running....");    }    @Override    public String method2() {        System.out.println("method2 running");        return "method2";    }    @Override    public int method3(int a) {        System.out.println("method3 running ....");        return a;    }}
package com.tangbaobao.reflect;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import org.junit.jupiter.api.Test;/** * @author 唐学俊 * @version 创建时间:2017年11月17日 下午3:17:02 * 测试方法 */public class ProxyTest {    @Test    public void test1() {        // 获取动态代理对象objProxy        TargetInterface objProxy = (TargetInterface) Proxy.newProxyInstance(                Target.class.getClassLoader(), // 类加载器                new Class[] { TargetInterface.class },                 new InvocationHandler() {                    @Override                    //invok代表执行代理对象的方法                    //method代表目标对象的字节码对象                    //args:代表目标的响应的方法的参数                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                        //目标方法前的逻辑                        System.out.println("目标方法前的逻辑");                        Object invoke = method.invoke(new Target(), args);                        System.out.println("目标方法后的逻辑");                        //目标方法后的逻辑                        return invoke;                    }              }         );        objProxy.method1();        String method2 = objProxy.method2();        System.out.println(method2);     }}

运行结果

这里写图片描述

package com.tangbaobao.reflect;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/*** @author 唐学俊* @version 创建时间:2017年11月17日 下午3:50:50* */public class ProxyTest2 {    public static void main(String[] args) {         Target  target = new Target();        //代理对象        TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(                target.getClass().getClassLoader(),                target.getClass().getInterfaces(),                new InvocationHandler() {                    @Override                    //invoke执行几次,看代理对象调用方法几次                    //代理对象调用接口方法都是调用invoke                    //proxy代理对象                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                        System.out.println("参数列表:"+args);                        Object invoke = method.invoke(target, args);                        return invoke;                    }                }          );        proxy.method1();//调用invoke        proxy.method2();//调用invoke        int method3 = proxy.method3(100);        System.out.println(method3);    }}

总结

动态代理是一种设计模式:可以增强方法,实现过滤…