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, 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的动态代理十分强大。
更多java代理模式与动态代理模式详解相关文章请关注PHP中文网!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

Java的类上载涉及使用带有引导,扩展程序和应用程序类负载器的分层系统加载,链接和初始化类。父代授权模型确保首先加载核心类别,从而影响自定义类LOA

本文讨论了使用咖啡因和Guava缓存在Java中实施多层缓存以提高应用程序性能。它涵盖设置,集成和绩效优势,以及配置和驱逐政策管理最佳PRA

本文讨论了使用JPA进行对象相关映射,并具有高级功能,例如缓存和懒惰加载。它涵盖了设置,实体映射和优化性能的最佳实践,同时突出潜在的陷阱。[159个字符]

本文讨论了使用Maven和Gradle进行Java项目管理,构建自动化和依赖性解决方案,以比较其方法和优化策略。

本文使用Maven和Gradle之类的工具讨论了具有适当的版本控制和依赖关系管理的自定义Java库(JAR文件)的创建和使用。
