JDK动态代理简单介绍

本文只是简单的对Java中的jdk代理进行记录,不做过于详细的原理分析(如需要,请移步其他)。

一、动态代理过程

在进行动态代理时,我们可以调用 java.lang.reflect.Proxy 包的 newProxyInstance() 方法。

为某些接口创建代理实例Foo的简略步骤如下:

   InvocationHandler handler = new MyInvocationHandler(...);
   Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                     new Class<?>[] { Foo.class },
                     handler);

二、newProxyInstance() 介绍

newProxyInstance方法签名

public static Object  newProxyInstance(
	ClassLoader  loader, 
	Class <?>[] interfaces, 
	InvocationHandler  h
	);

loader:定义代理类的类加载器。类加载器(将Class文件字节码内容加载到内存中,生成类对象)

interfaces:代理类要实现的接口列表。即这个代理类长什么样

h:将方法调用分派到的调用处理程序

三、InvocationHandler 介绍

InvocationHandler 是一个接口,需要实现下面的方法。
Object invoke(Object proxy, Method method, Object [] args);

new InvocationHandler() {

            //第一个参数:代理对象
            //第二个参数:需要重写目标对象的方法
            //第三个参数:method方法里面参数
            @Override
            public Object invoke(Object proxy,
                                 Method method,
                                 Object[] args) throws Throwable {

                //调用目标的方法
                Object result = method.invoke(target, args);
                
                return result;
            }
        };

proxy :调用该方法的代理实例

method:与在代理实例上调用的接口方法对应的 Method 实例。 Method 对象的声明类将是声明该方法的接口,它可能是代理类通过其继承该方法的代理接口的超接口。

args:包含在代理实例的方法调用中传递的参数值的对象数组,或者 null 如果接口方法不带参数。原始类型的参数包装在适当的原始包装类的实例中,例如 java.lang.Integer 或 java.lang.Boolean 。

其实这个proxy就是通过动态代理生成的对象,method是通过动态代理调用的方法,args是方法的参数。那就可以这个简单的理解proxy.method(args);
当然只是这么理解而已,调用过程并不是这样子。

四、具体使用实例

下面的例子,使用代理模式。使用上面提到的内容。

public class ProxyFactory {

    //目标对象
    private Object target;
    public ProxyFactory(Object target) {
        this.target = target;
    }

    //返回代理对象
    public Object getProxy() {
        /**
         * Proxy.newProxyInstance()方法
         * 有三个参数
         * 第一个参数:ClassLoader: 加载动态生成代理类的来加载器
         * 第二个参数: Class[] interfaces:目录对象实现的所有接口的class类型数组
         * 第三个参数:InvocationHandler:设置代理对象实现目标对象方法的过程
         */
        //第一个参数:ClassLoader: 加载动态生成代理类的来加载器
        ClassLoader classLoader = target.getClass().getClassLoader();
        //第二个参数: Class[] interfaces:目录对象实现的所有接口的class类型数组
        Class<?>[] interfaces = target.getClass().getInterfaces();
        //第三个参数:InvocationHandler:设置代理对象实现目标对象方法的过程
        InvocationHandler invocationHandler =new InvocationHandler() {

            //第一个参数:代理对象
            //第二个参数:需要重写目标对象的方法
            //第三个参数:method方法里面参数
            @Override
            public Object invoke(Object proxy,
                                 Method method,
                                 Object[] args) throws Throwable {

                //方法调用之前输出
                System.out.println("[动态代理][日志] "+method.getName()+",参数:"+ Arrays.toString(args));

                //调用目标的方法
                Object result = method.invoke(target, args);

                //方法调用之后输出
                System.out.println("[动态代理][日志] "+method.getName()+",结果:"+ result);
                return result;
            }
        };
        return Proxy.newProxyInstance(classLoader,interfaces,invocationHandler);
    }
}
  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值