设计模式之动态代理

动态代理:其实就是java.lang.reflect.Proxy类动态的根据您指定的所有接口生成一个class byte,该class会继承Proxy类,并实现所有你指定的接口(您在参数中传入的接口数组);然后再利用您指定的classloader将 class byte加载进系统,最后生成这样一个类的对象,并初始化该对象的一些值,如invocationHandler,以即所有的接口对应的Method成员。 初始化之后将对象返回给调用的客户端。这样客户端拿到的就是一个实现你所有的接口的Proxy对象

下面写一个demo:

父接口如下:

package wxtest.proxy;

public interface Character {
    public void run();

    public void eat();
}

子类如下:

class Student implements Character {
    private String name;

    public Student(String name) {
        this.name = name;
    }


    public void eat() {
        System.out.println("开始吃饭");
    }

    @Override
    public void run() {
        try {
            Thread.sleep(1000);
            //假设上交学费时间花了1s
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name + "上交学费10000");
    }

 代理StuInvocationHandler类如下 :

package wxtest.proxy;

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

public class StuInvocationHandler<T> implements InvocationHandler {
    //invocationHandler持有的被代理对象
    T target;

    public StuInvocationHandler(T target) {
        this.target = target;
    }

    /**
     * @param proxy  代表动态代理的真正的对象
     * @param method 代表正在执行的方法
     * @param args   代表调用目标方法时传入的实参
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("代理执行" + method.getName() + "方法");
        Object result = method.invoke(target, args);
        System.out.println(result);
        return null;
    }
}
测试代码如下:
public class dynamicProxy {


    public static void main(String[] args) {
        //被代理的学生Jet,这个对象是被代理的对象
        Character jet = new Student("jet");  //父类引用指向子类
        //创建一个与代理对象相关联的InvocationHandler
        InvocationHandler studentHandler = new StuInvocationHandler <Character>(jet); //创建该接口的代理类
        //创建一个代理对象stuProxy来代理jet,代理对象的每个执行方法都会替换执行Invocation中invoke方法
        Character stuProxy = (Character) Proxy.newProxyInstance(Character.class.getClassLoader(), new Class <?>[]{Character.class}, studentHandler);
        //代理执行上交班费的方法
        stuProxy.run();
        stuProxy.eat();
    }

}

输出结果如下:

代理执行run方法
jet上交学费10000
null
代理执行eat方法
开始吃饭
null

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值