当前位置: 移动技术网 > IT编程>开发语言>Java > java代理模式与动态代理模式详解

java代理模式与动态代理模式详解

2019年07月22日  | 移动技术网IT编程  | 我要评论
1、代理模式 所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之

1、代理模式

所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用。
代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。

生活中的例子:过年加班比较忙,没空去买火车票,这时可以打个电话到附近的票务中心,叫他们帮你买张回家的火车票,当然这会附加额外的劳务费。但要清楚票务中心自己并不卖票,只有火车站才真正卖票,票务中心卖给你的票其实是通过火车站实现的。这点很重要!

上面这个例子,你就是“客户”,票务中心就是“代理角色”,火车站是“真实角色”,卖票称为“抽象角色”!


代理模式java代码示例:
抽象角色:抽象类或接口

复制代码 代码如下:

interface business 

    void doaction(); 
}
 

真实角色:真正实现了业务逻辑接口

代理角色:自己并未实现业务逻辑接口,而是调用真实角色来实现

复制代码 代码如下:

class businessimplproxy implements business 

    private businessimpl bi; 
    public void doaction() 
    { 
        if (bi==null) 
        { 
            bi = new businessimpl(); 
        } 
        dobefore(); 
        bi.doaction(); 
        doafter(); 
    } 
    public void dobefore() 
    { 
        system.out.println("前置处理!"); 
    } 
    public void doafter() 
    { 
        system.out.println("后置处理!"); 
    } 

//测试类 
class test 

    public static void main(string[] args) 
    { 
        //引用变量定义为抽象角色类型 
        business bi = new businessimplproxy(); 
        bi.doaction(); 
    } 
}

复制代码 代码如下:

<span></span>

所以,借助于jvm的支持,可以在运行时动态生成代理类(“代理角色”),我们就可以解决上述代理模式中代码膨胀的问题,使用了动态代理后,“代理角色”将不用手动生成,而由jvm在运行时,通过指定类加载器、接口数组、调用处理程序这3个参数来动态生成。

动态代理模式java代码示例:

复制代码 代码如下:

import java.lang.reflect.invocationhandler;
 import java.lang.reflect.proxy;
 import java.lang.reflect.method;
 //抽象角色:java动态代理的实现目前只支持接口,不支持抽象类
 interface businessfoo
 {
     void foo();
 }
 interface businessbar
{
    string bar(string message);
}
//真实角色:真正实现业务逻辑方法
class businessfooimpl implements businessfoo
{
    public void foo()
    {
        system.out.println("businessfooimpl.foo()");
    }
}
class businessbarimpl implements businessbar
{
    public string bar(string message)
    {
        system.out.println("businessbarimpl.bar()");
        return message;
    }
}
//动态角色:动态生成代理类
class businessimplproxy implements invocationhandler
{
    private object obj;
    businessimplproxy() {
    }
    businessimplproxy(object obj) {
        this.obj = obj;
    }
    public object invoke(object proxy,method method,object[] args) throws throwable
    {
        object result = null;
        dobefore();
        result = method.invoke(obj,args);
        doafter();
        return result;
    }
    public void dobefore(){
        system.out.println("do something before business logic");
    }
    public void doafter(){
        system.out.println("do something after business logic");
    }
    public static object factory(object obj)
    {
        class cls = obj.getclass();
        return proxy.newproxyinstance(cls.getclassloader(),cls.getinterfaces(),new businessimplproxy(obj));
    }
}
//测试类
public class dynamicproxy
{   
    public static void main(string[] args) throws throwable
    {
        businessfooimpl bfoo = new businessfooimpl();
        businessfoo bf = (businessfoo)businessimplproxy.factory(bfoo);
        bf.foo();
        system.out.println();

        businessbarimpl bbar = new businessbarimpl();
        businessbar bb = (businessbar)businessimplproxy.factory(bbar);
        string message = bb.bar("hello,world");
        system.out.println(message);
    }
}

程序流程说明:
new businessfooimpl();创建一个“真实角色”,传递给工厂方法businessimplproxy.factory(),进而初始化“调用处理器”——即实现invocationhandler的类。并返回一个动态创建的代理类实例,由于“代理角色”也必然实现了“抽象角色”提供的业务逻辑方法,故可向下转型为businessbar,并赋值给指向businessbar类型的引用bb。
newproxyinstance(classloader loader, class<?>[] interfaces, invocationhandler h)方法由程序员来指定参数动态返回需要的代理类,而invoke(object proxy, method method, object[] args) 方法则是由jvm在运行时动态调用的。当执行“bb.bar("hello,world");”方法时,jvm动态指派“调用处理器”,向外层invoke传递参数,并调用method.invoke(obj,args)真正执行!

businessimplproxy.factory静态方法用来动态生成代理类(“代理角色”),在运行时根据不同的业务逻辑接口businessfoo和businessbar,在运行时分别动态生成了代理角色。“抽象角色”、“代理角色”以及调用处理器(实现invocationhandler接口的类)这三者都可以改变,所以说java的动态代理十分强大。

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网