JAVA设计模式-动态代理(Proxy)示例及说明
在Mybatis源码解析,一步一步从浅入深(五):mapper节点的解析文章的最后部分,我们提到了动态代理的概念,下面我们就简单了解一下动态代理。
一,概念
代理设计模式的目的就是在不直接操作对象的前提下对对象进行访问,实现这个目的得方法就是为目标对象创建一个代理(Proxy),通过代理来访问目标对象。这个设计模式的优点是什么呢?代码重用,符合开闭原则。
这样解释可能会不太好理解,那么接下来就通俗的来说一下代理:
1,不知道你知不知道VPN(也就是俗称的科学上网),在党的领导下,为了营造我国健康的的网络环境国外的一些网站在我国是无法访问的。例如:google。但是因为某些行业的特殊性需要访问这些国内不可访问的网站,那么怎么办呢?这个时候就需要代理(正向代理)了,怎么实现呢?例如:香港可以访问国内不可访问的网站,而国内却可以访问香港的网站。那么就可以这样做“国内->香港服务器(代理)->国外网站”。这里就用到了代理。
2,更通俗的例子就是,作者小的时候被狗狗追着跑,所以到现在作者看到狗狗,特别是体型庞大的狗狗的时候,就会害怕。假如一个狗狗有一天突然抢了作者的包子,那怎么办呢?那只能委托狗狗的主人,让狗狗把包子还给作者(r如果狗狗还没吃掉)。这里的主人也是扮演了代理的角色。
3,再来一个,作者是王力宏的歌迷。也一直很想点歌给王力宏唱。要怎么办?直接找他,估计没时间搭理我,最有希望的就是找他的经纪人,通过经纪人,传达我想点的歌。这个时候这个经纪人就是代理。
二,动态代理代码示例
那么接下来就以上面说到第三个例子,用代码展示一下代理模式。代理模式分为静态代理和动态代理,本文只说明动态代理。
1,王力宏是一个歌手,我们首先创建一个Singer接口类,并声明一个点歌和告别的方法
package com.zcz.proxyTest.testtwo;
public interface Singer {
/**
* 根据歌名点歌
* @param songName
*/
public void orderSong(String songName);
/**
* 向观众告别
* @param audienceName
*/
public void sayGoodBye(String audienceName);
}
2,接下来实现王力宏类,并实现接口中的两个方法。
package com.zcz.proxyTest.testtwo;
public class WangLiHong implements Singer {
@Override
public void orderSong(String songName) {
// TODO Auto-generated method stub
System.out.println("演唱歌曲:"+songName);
}
@Override
public void sayGoodBye(String audienceName) {
// TODO Auto-generated method stub
System.out.println("再见:"+audienceName);
}
}
3,就算我找到了经纪人(代理),那我也不能随便就叫经纪人通知(调用)王力宏(目标对象)唱歌(的方法),我还要准备一个感人肺腑的故事,但是我又不会讲故事,这个时候,经纪人就提供给了我一个模板(调用处理类,一个接口),让我按照模板编写故事(实现invoke方法)
package com.zcz.proxyTest.testtwo; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class MyStoryInvocationHandler implements InvocationHandler {
private Object object; public MyStoryInvocationHandler(Object o) {
// TODO Auto-generated constructor stub
this.object = o;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("力宏,我是你代理经纪人:"+proxy.getClass().getName());
//处理业务
System.out.println("巴拉巴拉......(讲了一个故事)"); for(Object arg:args) {
System.out.println("传入的参数:"+arg);
} //通过反射机制,通知力宏做事情
method.invoke(object, args); //处理业务
System.out.println("巴拉巴拉,感谢........"); return null;
} }
代码中的method.invoke方法使用到了反射机制,想要详细了解的可以查阅:Java程序语言的后门-反射机制
4,OK,到这里所有的准备工作就完成了,接下来就开始吧。
package com.zcz.proxyTest.testtwo;
import java.lang.reflect.Proxy;
public class MyPorxy {
public static void main(String[] args) {
//实例化目标对象(创造一个力宏)
WangLiHong liHong = new WangLiHong();
//实例化调用处理类(编好的故事)
MyStoryInvocationHandler handler = new MyStoryInvocationHandler(liHong);
//接下来创建代理(经纪人)
//准备一个类加载器
ClassLoader loader = MyPorxy.class.getClassLoader();
//获取目标对象的接口类对象数组
Class<?>[] interfaces = liHong.getClass().getInterfaces();
//创建代理
Singer proxy = (Singer) Proxy.newProxyInstance(loader, interfaces, handler);
//开始点歌
proxy.orderSong("就是现在");
System.out.println("****** 歌唱中......********");
//歌唱完了,say goodBye吧
proxy.sayGoodBye("zhangchengzi");
}
}
5,好,现在右键-> Run As -> Java Application。看打印结果:
力宏,我是你代理经纪人:com.sun.proxy.$Proxy0
巴拉巴拉......(讲了一个故事)
传入的参数:就是现在
演唱歌曲:就是现在
巴拉巴拉,感谢........
****** 歌唱中......********
力宏,我是你代理经纪人:com.sun.proxy.$Proxy0
巴拉巴拉......(讲了一个故事)
传入的参数:zhangchengzi
再见:zhangchengzi
巴拉巴拉,感谢........
6,看到了吗?我们不没有直接使用目标对象的方法,而是构造出一个代理对象,通过代理来访问了目标对象的方法。总结一下,想要实现动态代理需要四个关键元素
1,一个接口A
2,一个继承接口A,并实现A中抽象方法的实现类
3,一个实现了InvocationHandler的调用处理类
4,调用Proxy.newProxyInstance方法,获取代理类
7,OK,继续Mybatis源码解析吧:Mybatis源码解析,一步一步从浅入深(五):mapper节点的解析
8,虽然我们实现了一个动态代理的实例,但是你可能还更想清楚的了解动态代理的实现机制,不要着急,正好最近在找工作,有时间我们通过源代码继续深入的了解一下动态代理的实现机制。
相关java设计模式的文章:
JAVA设计模式-单例模式(Singleton)线程安全与效率
原创不易,转载请声明出处:https://www.cnblogs.com/zhangchengzi/p/9700248.html
JAVA设计模式-动态代理(Proxy)示例及说明的更多相关文章
- JAVA设计模式-动态代理(Proxy)源码分析
在文章:JAVA设计模式-动态代理(Proxy)示例及说明中,为动态代理设计模式举了一个小小的例子,那么这篇文章就来分析一下源码的实现. 一,Proxy.newProxyInstance方法 @Cal ...
- java --- 设计模式 --- 动态代理
Java设计模式——动态代理 java提供了动态代理的对象,本文主要探究它的实现, 动态代理是AOP(面向切面编程, Aspect Oriented Programming)的基础实现方式, 动态代理 ...
- 【设计模式】Java设计模式 - 动态代理
[设计模式]Java设计模式 - 动态代理 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 最近工作比较忙,没啥时间学习 目录 [设计模 ...
- Java的动态代理Proxy
概念梳理: 1.什么是动态代理? 答:动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实.代理一般会实现它所表示的实际对象的接口.代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际 ...
- Java 反射 设计模式 动态代理机制详解 [ 转载 ]
Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...
- 浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance
浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance java.lang.reflect.Proxy:该类用于动态生成代理类,只需传入目标接口.目标接口的类加载器以及Inv ...
- Java设计模式之代理模式(静态代理和JDK、CGLib动态代理)以及应用场景
我做了个例子 ,需要可以下载源码:代理模式 1.前言: Spring 的AOP 面向切面编程,是通过动态代理实现的, 由两部分组成:(a) 如果有接口的话 通过 JDK 接口级别的代理 (b) 如果没 ...
- 动态代理 Proxy InvocationHandler
前奏 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 代理类与委托类之间通常 ...
- java中动态代理实现机制
前言: 代理模式是常用的java设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系 ...
随机推荐
- idea(java)实用开发插件
Idea常用的插件: mybatisX, ---------------- (Alt + enter) codeGlace, Lombok, sonarlint, translation, ...
- [系列] 使用 go modules 包管理工具(一)
目录 概述 初始化 添加依赖包 go mod 命令 小结 源码地址 概述 我想实现一个开箱即用的 API 框架的轮子,这个轮子是基于 Gin 基础上开发的. 为什么是开箱即用,它会集成哪些功能? 以上 ...
- Keras实例教程(4)之迁移学习VGG
https://blog.csdn.net/baimafujinji/article/details/80743814
- ubuntu18.04安装docker
本文基于unbuntu18.04版本来安装docker,步骤如下: 1:右击桌面->打开终端(E). 2::输入以下命令: sudo snap install docker ,输入密码之后出下图 ...
- Guava google缓存机制
易百教程java学习http://www.yiibai.com/v3.php?app=all
- 浅谈jQuery中的Ajax
浅谈jQuery中的Ajax 一.前言 jQuery 对 Ajax 操作进行了封装, 在 jQuery 中最底层的方法时 $.ajax(), 第二层是 load(), $.get() 和 $.post ...
- Docker Machine的使用
前面两篇文章(<Asp.Net Core 发布到 Docker(Linux Centos 虚拟机,使用Dockerfile)> <Docker Compose的使用>),简单介 ...
- 第一篇 特征提取以及openvslam中的相关实现详解
参考尺度空间理论 金字塔 当用一个机器视觉系统分析未知场景时,计算机没有办法预先知道图像中物体尺度,因此,我们需要同时考虑图像在多尺度下的描述,获知感兴趣物体的最佳尺度.所以在很多时候,我们会在将图像 ...
- 牛客Wannafly挑战赛23 B.游戏
游戏 题目描述 小N和小O在玩游戏.他们面前放了n堆石子,第i堆石子一开始有ci颗石头.他们轮流从某堆石子中取石子,不能不取.最后无法操作的人就输了这个游戏.但他们觉得这样玩太无聊了,更新了一下规则. ...
- D-query
SPOJ - DQUERY 题意 求区间内出现一共有几种数字. 上次写了一个主席树,这次用一下莫队,莫队是离线询问的一种操作,将询问分块,如果在同一个块内就按照右端点排序,如果不在同一个块内就按照块的 ...