您好,欢迎访问一九零五行业门户网

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

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, class6b3d0130bba23ae47fe2b8e8cddf0195[] 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的动态代理十分强大。
更多java代理模式与动态代理模式详解。
其它类似信息

推荐信息