你好,游客 登录 注册 搜索
背景:
阅读新闻

Java 动态代理介绍及用法

[日期:2016-12-11] 来源:Linux社区  作者:nvd11 [字体: ]

一,静态代理模式的特点

在之前的文章中 Java代理模式 已经介绍里Java里的(静态)代理模式 http://www.linuxidc.com/Linux/2016-12/138191.htm

下面是上文静态代理类的例子:

public class ProxyBear implements Hitable<Dog>{  
    private Hitable<Dog> f = null;  
    public ProxyBear(){  
        if (null == f){  
            f = new Fox();  
        }  
    }  

    @Override  
    public void hit(Dog g){  
        if (null != f){  
            System.out.println("Bear hit InterDogChicken!");  
            f.hit(g);  
            System.out.println("Bear bite InterDogChicken!");  
        }  
    }  

从代码可以看出, 上面代理类可以增强被代理的对象的某个方法。
但是被代理对象的类型Hitable是指定1个接口(或抽象类)

也就是讲上静态代理类只适用于某一种指定的接口实现类, 如果某个对象没有实现揍狗接口, 而是其他另1个接口, 那么就必须新建1个代理类的。即使新代理类也是实现同样的功能

二. 动态代理的1个需求

就用会上文的例子

我们宜家有两个接口。殴打和调戏接口..

殴打接口 Hitable

public interface Hitable<T> {
    public void hit(T o);
}

调戏接口 Molestable

public interface Molestable<T> {
    public void molest(T o);
}

其中狐狸类实现了殴打狗接口

public class Fox implements Hitable<Dog> {
    @Override
    public void hit(Dog g){
        this.sap(g);
        this.uppercut(g);
    }

    //闷棍
    private void sap(Dog g){
        System.out.println("give " + g.getName() + " a Sap!");
    }

    //上勾拳
    private void uppercut(Dog g){
        System.out.println("give " + g.getName() + " a Uppercute!");
    }
}

狼类实现调戏狗接口

public class Wolf implements Molestable<Dog> {
    @Override
    public void molest(Dog o) {
        System.out.println("wolf laugh at the dog!");
        System.out.println("wolf ruffle the dog!");
    }
}

这个是万恶的狗类

public class Dog {
    private String name;
    public Dog(String name){
        this.setName(name);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Dog [name=" + name + "]";
    }
}

问题来了, 依家狗太恶, 狼和狐狸都要找头熊(代理)看着才敢去惹狗

如果用静态代理, 就如本文一开始的那个代理类, 则只能单独为狐狸or 狼代理, 这个需求需要两个代理类, 因为狗和狐狸实现的是两个不同的接口

如下图
Alt text

那么有没有一种代理类, 可以同时代理多个接口的实现类呢,java 里动态代理就利用了反射实现了这个功能。

三,动态代理的例子

我们利用动态代理类重新写了1个熊类出来:

public class dynamicProxyBear implements InvocationHandler {
    //delegate means proxy
    //the object which will be delegated
    private Object delegate;

    public Object bind(Object delegate){
        this.delegate = delegate;

        /**
         * This method newProxyInstance return ***one of the interfaces*** of delegate object(properties object of this class)
         * 
         * @param 
         *      1.ClassLoader loader -> usually use delegate object's class loader
         *      2.Class<?>[] interfaces -> collection of the interface which delegate object has implemented
         *      3.InvocationHandler h -> this
         * @return
         */
        return Proxy.newProxyInstance(delegate.getClass().getClassLoader(), 
                                      delegate.getClass().getInterfaces(), this);

    }

    /**
     * This method will replace all the method owned by delegate object.
     * @param proxy -> the delegate object, never use it's method directly, otherwise will lead to Dead loop
     * @param method -> the method (once execute will fall into this invoke method) object of delegate object 
     * @param args  -> parameters of the mothod.
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Object result;

        if (args.length < 1){
            return method.invoke(this.delegate,args);
        }

        //bear watching
        System.out.println("bear is watching " + args[0].toString());
        result = method.invoke(this.delegate,args);
        System.out.println("bear leaved " + args[0].toString());
        return result;
    }
}

更多详情见请继续阅读下一页的精彩内容http://www.linuxidc.com/Linux/2016-12/138192p2.htm

linux
相关资讯       Java动态代理 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款