Java代理(三) JDK动态代理

定义

动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。

实现方式


在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface)、另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的。

每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。

java.lang.reflect.InvocationHandler#invoke
//proxy:指我们所代理的那个真实对象//method:真实对象调用的方法//args:传入方法的参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
可以看出,现在还不知道代理类对象是什么,这用到了另一个类:java.lang.reflect.Proxy
Proxy类的作用就是用来动态创建一个代理对象的类,它提供了许多的方法,但是我们用的最多的就是 newProxyInstance 这个方法

//返回 动态的代理对象
//loader: 加载代理对象的ClassLoader//interfaces:一个Interface对象的数组,代理类实现的这些接口列表//h:关联到的InvocationHandler对象
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

Java代码案例:
package com.tlk.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Created by tanlk on 2017/8/16 17:32.
 */
public class JDKDynamicProxyTest {

    interface Subject {
        public void test1();

        public void test2();
    }

    /**
     * 实现类1
     */
    static class MySubject1 implements Subject {
        public void test1() {
            System.out.println("MySubject1 test1 方法开始执行");
        }

        public void test2() {
            System.out.println("MySubject1 test2 方法开始执行");
        }
    }

    /**
     * 实现类2
     */
    static class MySubject2 implements Subject {
        public void test1() {
            System.out.println("MySubject2 test1 方法开始执行");
        }

        public void test2() {
            System.out.println("MySubject2 test2 方法开始执行");
        }
    }

    /**
     * 定义一个动态代理类,动态代理类必须要实现InvocationHandler接口
     */
    static class DynamicProxy implements InvocationHandler {

        private Subject target;

        //当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("before ");
            method.invoke(target, args);
            System.out.println("end");
            return null;
        }

        //通过Proxy的newProxyInstance方法来创建我们的代理对象
        public Object getProxy(Subject target) {
            this.target = target;
            //动态生成代理类
            return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        }
    }

    public static void main(String[] args) {
        DynamicProxy dynamicProxy = new DynamicProxy();
        Subject subject = (Subject) dynamicProxy.getProxy(new MySubject1());
        System.out.println("生成的代理类:" + subject.getClass());
        subject.test1();

        subject = (Subject) dynamicProxy.getProxy(new MySubject2());
        System.out.println("生成的代理类:" + subject.getClass());
        subject.test2();
    }

}



动态代理优点:
1.上面只有一个proxy类,但可以代理多个实现,而静态代理需要n个proxy类
2.通过invoke方法,在所有被代理的类的某些函数调用时触发,一口气完成所有对应代理的AOP(静态代理需要在每个代理上进行AOP)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值