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设计模式-动态代理(Proxy)示例及说明

  JAVA设计模式-动态代理(Proxy)源码分析

  JAVA设计模式-单例模式(Singleton)线程安全与效率

  


原创不易,转载请声明出处:https://www.cnblogs.com/zhangchengzi/p/9700248.html

JAVA设计模式-动态代理(Proxy)示例及说明的更多相关文章

  1. JAVA设计模式-动态代理(Proxy)源码分析

    在文章:JAVA设计模式-动态代理(Proxy)示例及说明中,为动态代理设计模式举了一个小小的例子,那么这篇文章就来分析一下源码的实现. 一,Proxy.newProxyInstance方法 @Cal ...

  2. java --- 设计模式 --- 动态代理

    Java设计模式——动态代理 java提供了动态代理的对象,本文主要探究它的实现, 动态代理是AOP(面向切面编程, Aspect Oriented Programming)的基础实现方式, 动态代理 ...

  3. 【设计模式】Java设计模式 - 动态代理

    [设计模式]Java设计模式 - 动态代理 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 最近工作比较忙,没啥时间学习 目录 [设计模 ...

  4. Java的动态代理Proxy

    概念梳理: 1.什么是动态代理? 答:动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实.代理一般会实现它所表示的实际对象的接口.代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际 ...

  5. Java 反射 设计模式 动态代理机制详解 [ 转载 ]

    Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...

  6. 浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance

    浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance java.lang.reflect.Proxy:该类用于动态生成代理类,只需传入目标接口.目标接口的类加载器以及Inv ...

  7. Java设计模式之代理模式(静态代理和JDK、CGLib动态代理)以及应用场景

    我做了个例子 ,需要可以下载源码:代理模式 1.前言: Spring 的AOP 面向切面编程,是通过动态代理实现的, 由两部分组成:(a) 如果有接口的话 通过 JDK 接口级别的代理 (b) 如果没 ...

  8. 动态代理 Proxy InvocationHandler

      前奏 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 代理类与委托类之间通常 ...

  9. java中动态代理实现机制

    前言: 代理模式是常用的java设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系 ...

随机推荐

  1. static用法总结:

    这是我的第一篇随笔! 1.当1.cpp和2.cpp都定义了同一个全局时链接会报错,变量名冲突.需要将其中一个设置为static控制其作用域为只在一个源文件内部. 2.函数名也是全局的,故static的 ...

  2. 使用spark dataSet 和rdd 解决 某个用户在某个地点待了多长时间

    现有如下数据文件需要处理格式:CSV位置:hdfs://myhdfs/input.csv大小:100GB字段:用户ID,位置ID,开始时间,停留时长(分钟) 4行样例: UserA,LocationA ...

  3. 【目标检测】RCNN算法详解

    网址: 1. https://blog.csdn.net/zijin0802034/article/details/77685438 (box regression 边框回归) 2. https:// ...

  4. 人员考勤,MySQLl数据库一个表自动生成3表筛选人员迟到早退缺勤

    前言:漂亮的人事小姐姐找我帮忙弄考勤:由于人员考勤和门禁一起,打卡记录太多,打卡机只能导出一个打卡Excel总表,不容易人工筛选. Excel表的格式是这样的:(这里101代替真实人名) 实现目标: ...

  5. CodeForces 1058E

    题意略. 思路:本题有两个关键点: 一.满足题设的区间条件 1.区间内1的个数和为偶数 2.区间内含1个数最多的那一项,它所含1的个数不得超过区间内1的个数和的一半. 二.长度超过60的区间必然满足上 ...

  6. React生命周期函数理解

    一.组件挂载阶段 1. componentWillMount() 该方法在首次渲染之前调用,在一个组件挂载到卸载的过程中,仅仅执行这一次.该函数内可以state初始化的工作,与constructor的 ...

  7. Fedora7 安装完全过程

    操作系统课要用Fedora7 安装配置真是一把辛酸泪呀..... 首先是找镜像文件(这个就找了好久.....): https://archives.fedoraproject.org/pub/arch ...

  8. 通过脚本实现将服务器的Log实时传送到Telegram群组

    首先说下需求,IT老大提出的一个需求,实现将php-laravel的应用日志实时传送到telegram的监控群组中,不用登陆服务器就可以实时查看应用的日志. 具体思路是: 先要将日志切割,并实时更新这 ...

  9. GIT常见问题及其解决方案

    问题: remote: Permission to beijing01/learn_github.git denied to liuhongyang02. fatal: unable to acces ...

  10. MVC设计模式用于用户注册表单提交到数据库的中文乱码问题

    本文引用自:http://blog.csdn.net/wangchangshuai0010/article/details/12714575 java.sql.SQLException: Incorr ...