代理的概念:为某个对象提供一个代理,以控制对这个对象的访问。 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类处理、以及委托类执行完请求后的后续处理。
    抽象对象角色:就是代理类和委托类共同的接口,声明了目标对象和代理对象的共同接口,这样一来在任何可以使用目标对象的地方都可以使用代理对象。
目标对象角色:就是委托类,定义了代理对象所代表的目标对象。
代理对象角色:就是代理类,代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象提供一个与目标对象相同的接口,以便可以在任何时候替代目标对象。代理对象通常在客户端调用传递给目标对象之前或之后,执行某个操作,而不是单纯地将调用传递给目标对象。 静态代理
代理类在程序运行前已经存在的代理方式称为静态代理。 /**
* 定义Demo接口
*/
public interface Demo {
public void save();
} /**
* DemoImpl实现Demo接口并覆写save()方法
* 真实主题,执行具体业务
*/
public class DemoImpl implements Demo {
public void save() {
System.out.println("调用save()方法");
}
} /**
* DemoImplProxy 也实现了Demo接口,并覆写了save()方法,增加了自己的业务
* 代理主题,负责其他业务的处理
*/
public class DemoImplProxy implements Demo {
Demo demoImpl = new DemoImpl(); public void save() {
System.out.println("开始记录日志");
demoImpl.save();
System.out.println("开始结束日志");
}
} 静态代理有一个缺点,每个代理类只能为一个接口服务,这样程序开发中必然会产生许多的代理类。
动态代理
代理类在程序运行前不存在、运行时由程序动态生成的代理方式称为动态代理。
实现动态代理包括三步: (1). 新建代理类和委托类共同的接口以及委托类;
(2). 实现InvocationHandler接口,这是负责连接代理类和委托类的中间类必须实现的接口;
(3). 通过Proxy类新建代理类对象。 第一步:新建代理类和委托类共同的接口以及委托类 public interface Operate { public void operateMethod1(); public void operateMethod2(); public void operateMethod3();
} public class OperateImpl implements Operate { @Override
public void operateMethod1() {
System.out.println("Invoke operateMethod1");
sleep(110);
} @Override
public void operateMethod2() {
System.out.println("Invoke operateMethod2");
sleep(120);
} @Override
public void operateMethod3() {
System.out.println("Invoke operateMethod3");
sleep(130);
} private static void sleep(long millSeconds) {
try {
Thread.sleep(millSeconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} 第二步:实现InvocationHandler接口 java.lang.reflect.InvocationHandler接口的定义如下: /**
*
*Object proxy:被代理的对象
*Method method:要调用的方法
*Object[] args:方法调用时所需要参数
*/
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
} 实现 InvocationHandler 接口 public class TimingInvocationHandler implements InvocationHandler { private Object target;
public TimingInvocationHandler() {}
public TimingInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long start = System.currentTimeMillis();
Object obj = method.invoke(target, args);
System.out.println(method.getName() + " cost time is:" + (System.currentTimeMillis() - start));
return obj;
}
} 第三步:通过Proxy类新建代理类对象 java.lang.reflect.Proxy类的定义如下: /**
*CLassLoader loader:类的加载器
*Class<?> interfaces:得到全部的接口
*InvocationHandler h:得到InvocationHandler接口的子类的实例
*/
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException public class Main {
public static void main(String[] args) {
// create proxy instance
TimingInvocationHandler timingInvocationHandler = new TimingInvocationHandler(new OperateImpl());
Operate operate = (Operate)(Proxy.newProxyInstance(Operate.class.getClassLoader(), new Class[] {Operate.class},
timingInvocationHandler)); // call method of proxy instance
operate.operateMethod1();
System.out.println();
operate.operateMethod2();
System.out.println();
operate.operateMethod3();
}
} 下面总结一下动态代理对象创建过程 // InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发
// 其内部通常包含指向委托类实例的引用,用于真正执行分派转发过来的方法调用
InvocationHandler handler = new InvocationHandlerImpl(..); // 通过 Proxy 为包括 Interface 接口在内的一组接口动态创建代理类的类对象
Class clazz = Proxy.getProxyClass(classLoader, new Class[] { Interface.class, ... }); // 通过反射从生成的类对象获得构造函数对象
Constructor constructor = clazz.getConstructor(new Class[] { InvocationHandler.class }); // 通过构造函数对象创建动态代理类实例
Interface Proxy = (Interface)constructor.newInstance(new Object[] { handler }); 从上面可以看到,实际使用过程更加简单,因为 Proxy 的静态方法 newProxyInstance 已经为我们封装了步骤 2 到步骤 4 的过程,所以简化后的过程如下 // InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发
InvocationHandler handler = new InvocationHandlerImpl(..); // 通过 Proxy 直接创建动态代理类实例
Interface proxy = (Interface)Proxy.newProxyInstance( classLoader,
new Class[] { Interface.class },
handler ); 参考文章: Java 动态代理机制分析 公共技术点之 Java 动态代理 代理模式和android插件化 Android设计模式源码解析之Proxy模式

Android中的代理模式的更多相关文章

  1. Objective-C中的委托(代理)模式

    我个人更喜欢把委托(Delegate)模式称为代理(Proxy)模式.还是那句话,第一次接触代理模式是在Java中接触的,在Java中实现代理模式和接口是少不了的.当时学习Spring的时候用到了接口 ...

  2. OC中的代理模式

    OC中的代理模式,关于代理模式,如果还有同学不太清楚的话,就自己去补充知识了,这里就不做介绍了,这里只介绍OC中是如何实现代理模式的.这里举一个简单的例子:小孩类,护士类,保姆类,其中小孩类有两个方法 ...

  3. (转)轻松学,Java 中的代理模式及动态代理

    背景:讲到反射机制,肯定会想到动态代理. 轻松学,Java 中的代理模式及动态代理 代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强.值得注意的是,代理类和被代理类应该 ...

  4. 简介Python设计模式中的代理模式与模板方法模式编程

    简介Python设计模式中的代理模式与模板方法模式编程 这篇文章主要介绍了Python设计模式中的代理模式与模板方法模式编程,文中举了两个简单的代码片段来说明,需要的朋友可以参考下 代理模式 Prox ...

  5. 「补课」进行时:设计模式(5)——从 LOL 中学习代理模式

    1. 前文汇总 「补课」进行时:设计模式系列 2. 从 LOL 中学习代理模式 我是一个很喜欢玩游戏的人,虽然平时玩游戏的时间并不多,但我也是一个忠实的 LOL 的爱好者,就是段位有点惨不忍睹,常年倔 ...

  6. 理解Android系统的进程间通信原理(一)----RPC中的代理模式

    Android系统中的进程间通信是通过一个轻量级的RPC(Remote Procedure Call远程进程调用)和AIDL(Android Interface Definination Langua ...

  7. Java中的代理模式

    代理模式在Java Web的框架中经常使用到.比如说在对数据库的访问中,核心功能是对数据库的增删改查,而连接数据库.处理事务等功能我们在开发中也要考虑到.所以我们将数据库的CRUD抽象到接口中,然后实 ...

  8. Android中的启动模式(下)

    在这篇文章中,我会继续跟大家分享有关于Android中启动模式的相关知识.当然,如果对这个启动模式还不完全了解或者没有听过的话,可以先看看我之前写的有关于这个知识点的入门篇Android的启动模式(上 ...

  9. 说说Java中的代理模式

    今天看到传智播客李勇老师的JDBC系列的第36节——通过代理模式来保持用户关闭连接的习惯.讲的我彻底蒙蔽了,由于第一次接触代理模式,感到理解很难,在博客园找到一篇文章,先记录如下: 引用自java设计 ...

随机推荐

  1. 问答项目---用户注册的那些事儿(JS验证)

    做注册的时候,由于每一个页面都有都要可以注册,可以把注册方法写到一个公用的方法里去,其他方法继承这个方法: 简单注册JS示例: <script type='text/javascript'> ...

  2. 170630、springboot编程之普通类中调用spring管理的bean对象

    我们知道如果我们要在一个类使用spring提供的bean对象,我们需要把这个类注入到spring容器中,交给spring容器进行管理,但是在实际当中,我们往往会碰到在一个普通的Java类中,想直接使用 ...

  3. OleDb未指定错误

    桌面开发,居然也出这种问题: 1. C#读取Excel“未指定错误” http://www.connectionstrings.com/ http://www.dnetzj.com/Content/2 ...

  4. spring requestmapping 拦截多个请求

    @RequestMapping(value = {"/picture_content/{id}","/attachment_content/{id}",&quo ...

  5. CentOS7.5基础优化与常用配置

    目录 最小化全新安装CentOS7基础优化 配置yum源 安装常用软件 关闭防火墙 关闭SELinux 优化ulimit 历史命令记录改为1万条 把命令提示符改为绿色 添加vim配置文件 添加一个普通 ...

  6. 解决maven的依赖总是无法下载完成

    有时候在eclipse里面刚刚导进一个maven项目,但是总是无法完整下载pom文件里面的依赖 主要有两个原因: 1,需要下载的依赖(jar包)需要开发人员给权限(远程仓库的下载权限),这个可以找开发 ...

  7. cocos-lua基础学习(八)Layer类学习笔记

    创建 local layer = cc.Layer:create() local layer1 = cc.LayerColor:create(cc.c4b(192, 0, 0, 255), s.wid ...

  8. 1:3访问 servlet API 的两种方式(request,session等内置对象)

    1:解耦方式 2:耦合方式: ========================================== ========================================== ...

  9. appscan 9.0.3.10 版本下载

    http://download4.boulder.ibm.com/sar/CMA/RAA/07ukf/0/ 其他版本下载 https://www.cnblogs.com/hua198/p/100447 ...

  10. vue版本,小Toast

    <div id="message" :class="{'show':show_Message}"><p v-html="messag ...