MyBatis源码解析【4】反射和动态代理
通过之前的介绍,我们了解了几个组件的生命周期。
它也是我们重要装备之一。
今天我们需要搞一件更加强的装备,叫做反射和动态代理。
如果没有这件装备的话,显然后面的源码boss是打不动的。
顺便说一下,下面可能会提到一些名词简写,都在之前出现过,所以如果看不明白可以看一下之前的咯。
废话少说,╭(′▽`)╯
什么是代理
首先我们要明白代理是什么样一个概念。
不要想这个概念有多复杂,其实很简单的。代理从中文角度很好理解嘛。它是一个动词吧,举个实际的例子,你代理我,帮我抄作业。
我--->你--->作业
你代理我,相当于我让你做,或者你帮我做。
最终抄作业这个事情呢是由你来完成的。嘻嘻。
注意这个例子的两个关键:
1、我没有直接操作真实的最终的对象。(我没有抄作业)
2、你可以提供额外的服务,比如告诉我作业抄好了,或者明天有什么作业。
那么认真的讲:
通过代理模式,访问者没有办法操作真实的对象,只能通过代理对象去操作真实的对象。代理对象可以提供额外的服务,比操作真实对象更多的服务。
什么是反射
是不是很多人当提到这个概念有下面几个感觉:1、反射学过没用过。2、反射很难,但是没啥用。3、反射很危险,没事情不要乱用。
如果你有这么几个概念的话,证明你已经对反射有一些学习和感觉了(滑稽脸)。
如果没有的话,我建议呢,还是去好好找个大神的博客或者视频学习一下反射。因为不简单,听我一两句可能不一定明白。
那我们这里用到反射,需要知道这几个点。
1、在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。
2、对于任意一个对象,都能够调用它的任意方法和属性;生成动态代理。
3、通过一些特殊的方法得到对象,calss.forname等
知道这些就可以了。
如果你愿意呢,可以看一下我以前写的关于反射的几个小例子,希望能帮到你:http://www.cnblogs.com/linkstar/p/5744444.html
什么是动态代理
动态代理其实上面在说代理的时候以及提到了。其实就是动态的代理嘛。
动态代理这里介绍两种:一种使用JDK的反射机制提供的代理,另一种是CGLIB代理。
我们一种种来讲。
JDK的动态代理。
如何实现呢?很简单,完成两个类就可以了。
1、服务类,也就是真正提供服务的人。
2、代理类,代理做事情的人。
对于JDK的动态代理的服务类来说需要额外一个接口开放给代理类哦。
下面是代码
接口
public interface DemoService {
public void demo();
}
实现类
public class DemoServiceImpl implements DemoService {
public void demo() {
System.out.println("Test------------");
}
}
代理类
public class DemoServiceProxy implements InvocationHandler { private Object target; public Object bind(Object target){
this.target = target;
//利用反射将这个类DemoServiceProxy作为传入的目标类的代理类
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
} //代理方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("method : " + method.getName());
return method.invoke(target, args);
}
}
测试类
public class DemoServiceTest {
public static void main(String[] args) {
DemoServiceProxy demoServiceHanler = new DemoServiceProxy();
DemoService proxy = (DemoService) demoServiceHanler.bind(new DemoServiceImpl());
proxy.demo();
}
}
最后打印结果
method : demo
Test------------
这里的这几个类的作用和功能要好好理解哦,因为后面读源码的时候需要用到。
然后是CGLIB代理
相对来说就没有那么复杂了,只需要一个类就可以了,不需要接口。
public class DemoServiceCglib implements MethodInterceptor { private Object target; public Object getInstance(Object target){
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
} public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("method : " + method.getName());
return proxy.invokeSuper(obj, args);
}
}
测试类修改
public class DemoServiceTest {
public static void main(String[] args) {
/*DemoServiceProxy demoServiceHanler = new DemoServiceProxy();
DemoService proxy = (DemoService) demoServiceHanler.bind(new DemoServiceImpl());
proxy.demo();*/
DemoServiceCglib demoServiceCglib = new DemoServiceCglib();
DemoService proxy = (DemoService) demoServiceCglib.getInstance(new DemoServiceImpl());
proxy.demo();
}
}
测试结果相同。
这里就不深究两种动态代理的各种参数啊,方法啊。
我们需要知道的是,在被动态代理之后,当我们调用原来的方法时候一定调用一个叫做invoke的方法。
也就是在调用的前后我们能做很多事情了。
上述在mybatis的源码中会出现,很重要,望理解。
至此,装备都有了,之后就要开始进入难点了。
MyBatis源码解析【4】反射和动态代理的更多相关文章
- 初看Mybatis 源码 (二) Java动态代理类
先抛出一个问题,用过Mybatis的都知道,我们只需要定义一个Dao的接口,在里面写上一些CRUD相关操作,然后配置一下sql映射文件,就可以达到调用接口中的方法,然后执行sql语句的效果,为什么呢? ...
- MyBatis源码解析之数据源(含数据库连接池简析)
一.概述: 常见的数据源组件都实现了javax.sql.DataSource接口: MyBatis不但要能集成第三方的数据源组件,自身也提供了数据源的实现: 一般情况下,数据源的初始化过程参数较多,比 ...
- Mybatis源码解析(四) —— SqlSession是如何实现数据库操作的?
Mybatis源码解析(四) -- SqlSession是如何实现数据库操作的? 如果拿一次数据库请求操作做比喻,那么前面3篇文章就是在做请求准备,真正执行操作的是本篇文章要讲述的内容.正如标题一 ...
- mybatis源码-解析配置文件(四-1)之配置文件Mapper解析(cache)
目录 1. 简介 2. 解析 3 StrictMap 3.1 区别HashMap:键必须为String 3.2 区别HashMap:多了成员变量 name 3.3 区别HashMap:key 的处理多 ...
- mybatis源码-解析配置文件(四)之配置文件Mapper解析
在 mybatis源码-解析配置文件(三)之配置文件Configuration解析 中, 讲解了 Configuration 是如何解析的. 其中, mappers作为configuration节点的 ...
- mybatis源码-解析配置文件(三)之配置文件Configuration解析
目录 1. 简介 1.1 系列内容 1.2 适合对象 1.3 本文内容 2. 配置文件 2.1 mysql.properties 2.2 mybatis-config.xml 3. Configura ...
- Mybatis源码解析,一步一步从浅入深(四):将configuration.xml的解析到Configuration对象实例
在Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码中我们看到了XMLConfigBuilder(xml配置解析器)的实例化.而且这个实例化过程在文章:Mybatis源码解析,一步一步从浅 ...
- Mybatis源码解析,一步一步从浅入深(五):mapper节点的解析
在上一篇文章Mybatis源码解析,一步一步从浅入深(四):将configuration.xml的解析到Configuration对象实例中我们谈到了properties,settings,envir ...
- Mybatis源码解析,一步一步从浅入深(六):映射代理类的获取
在文章:Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码中我们提到了两个问题: 1,为什么在以前的代码流程中从来没有addMapper,而这里却有getMapper? 2,UserDao ...
- Mybatis源码解析(三) —— Mapper代理类的生成
Mybatis源码解析(三) -- Mapper代理类的生成 在本系列第一篇文章已经讲述过在Mybatis-Spring项目中,是通过 MapperFactoryBean 的 getObject( ...
随机推荐
- swift 取消UIButton选中高亮状态
objc可以用通过重写setHighlighted方法来达到当按钮选中时的高亮状态 -(void)setHighlighted:(BOOL)highlighted{ } swift中取消高亮状态 ov ...
- LR11 scan correlation 卡死解决方案
LR11 scan correlation 卡死解决方案 笔者在录制脚本时是勾选Enable correlation during recording的,导致后续每次脚本回放都会弹出scan corr ...
- 移动端车牌识别——可以嵌入智能手机系统里的新OCR识别技术
移动端车牌识别技术,是在OCR光学字符识别技术的基础上研发的用来识别汽车号牌特征信息的图像识别技术.在国内,该项技术由北京易泊时代携手清华大学成功地将"国家863计划"项目成果-- ...
- AVL树(平衡二叉查找树)
首先要说AVL树,我们就必须先说二叉查找树,先介绍二叉查找树的一些特性,然后我们再来说平衡树的一些特性,结合这些特性,然后来介绍AVL树. 一.二叉查找树 1.二叉树查找树的相关特征定义 二叉树查找树 ...
- 玩转nodeJS系列:使用原生API实现简单灵活高效的路由功能(支持nodeJs单机集群),nodeJS本就应该这样轻快
前言: 使用nodeJS原生API实现快速灵活路由,方便与其他库/框架进行整合: 1.原生API,简洁高效的轻度封装,加速路由解析,nodeJS本就应该这样轻快 2.不包含任何第三方库/框架,可以灵活 ...
- 关于安卓百度地图SDK报错:Multiple dex files define Lcom/baidu/android/bbalbs/common/a/a;
1.找到.jar包 2.右键,用WinRAR打开 3.打开com/baidu/ 4.保留location,其他全删掉 5.这样将不会报错,可以运行了!!!
- 关于前后端同构,我的一点思路和心得(vue、nodejs、react、模版、amd)
最近1年多,前后端同构慢慢变成一个流行词,也许很多人还停留在前后端分离的最佳实践道路上,但实际上又有一批人已经从简单的服务端渲染走向探索最佳前后端同构方案的路上了.不过,我只是膜拜后者的过客. 虽然大 ...
- 【转载】图文详解 IntelliJ IDEA 15 创建普通 Java Web 项目
第 1 部分:新建一个 Java Web Application 项目 File -> New -> Project-,请选择 Java EE 这个模块下的 Web Application ...
- 【原创】源码角度分析Android的消息机制系列(一)——Android消息机制概述
ι 版权声明:本文为博主原创文章,未经博主允许不得转载. 1.为什么需要Android的消息机制 因为Android系统不允许在子线程中去访问UI,即Android系统不允许在子线程中更新UI. 为什 ...
- mac os 安装 wget
1. brew安装: ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/inst ...