java学习笔记之动态代理

1、  什么是动态代理?

代理是基本的设计模式之一。它是你为了提供额外的或者不同的操作,而插入的用来代替“实际”的对象的对象。这些操作经常涉及与“实际”对象的通信,所以代理通常充当中间人的角色。Java动态代理的思想比代理更向前迈进了一步,因为它可以动态的创建代理并动态的处理对所代理方法的调用。在动态代理上所做的所有调用都会被重定向到单一的调用处理器上,它的工作是揭示调用的类型并确定响应的政策。

2、  动态代理可以用来做什么?

动态代理的用途与装饰模式很相似,就是为了对某个对象进行增强。所有使用装饰者模式的案例都可以使用动态代理来替换。动态代理就是在运行时生成一个类,这个类会实现你指定的一组接口,而这个类没有.java文件,是在运行时生成的,你也不用去关心它是什么类型的,你只需要知道它实现了哪些接口即可。动态代理技术都是在框架中使用,例如:Struts1、Struts2、Spring和Hibernate中都使用了动态代理技术。所有学好动态代理对以后框架的学习很有好处!

3、  怎么使用动态代理?

3.1、静态方法Proxy.newProxyInstance()创建动态代理,方法需要三个参数,下面一一介绍

l  ClassLoader loader:它是类加载器类型,今天不在这说它,以后专门开专题写它,我们只需要知道怎么可以获得它就可以了:XXX.class.getClassLoader()就可以获取到ClassLoader对象,没错,只要你有一个Class对象就可以获取到ClassLoader对象;

l  Class[] interfaces:指定newProxyInstance()方法返回的对象要实现哪些接口,没错,可以指定多个接口

l  InvocationHandler h:它是最重要的一个参数!它是一个接口!它的名字叫调用处理器!InvocationHandler接口只有一个方法,即invoke()方法!它是对代理对象所有方法的唯一实现。也就是说,无论你调用代理对象上的哪个方法,其实都是在调用InvocationHandler的invoke()方法。

3.2、InvocationHandler的invoke()方法,同样需要三个参数:

l  Object proxy:代理对象,也就是Proxy.newProxyInstance()方法返回的对象,通常我们用不上它。

l  Method method:表示当前被调用方法的反射对象,例如mi.fun1(),那么method就是fun1()方法的反射对象

l  Object[] args:表示当前被调用方法的参数,当然mi.fun1()这个调用是没有参数的,所以args是一个零长数组。

最后,invoke()方法的返回值为Object类型,它表示当前被调用的方法的返回值。

4、  代码实例


interface waiter{
    public void serve();
}

class MyWaiter implements waiter{

    public void serve() {
        System.out.println("服务。。。");
    }
}

/**
 * 目标:对服务生对象进行增强,在服务前后添加“您好”和“欢迎光临”!
 * 手段:动态代理
 * @author Jason
 *
 */
public class MainApp1 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ClassLoader loader = MainApp1.class.getClassLoader();
        Class[] c = {waiter.class};
        waiter target = new MyWaiter();
        MyInvocationHandler h = new MyInvocationHandler(target);
        //创建动态代理,传递参数
        waiter waiter1 = (waiter) Proxy.newProxyInstance(loader, c, h);
        waiter1.serve();
    }
}

class MyInvocationHandler implements InvocationHandler{
    private waiter target;
    
    public MyInvocationHandler(waiter target){
        this.target = target;
    }
    
    /*
     * 调用serve方法都会调用这个方法
     *
     */
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("您好。。。");
        Object result = method.invoke(target, args);
        System.out.println("欢迎下次光临!");
        return result;
    }    
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值