上一篇博客说到mybatis对日志的实现有一个优先顺序,本篇以jdkLog为例探讨mybatis运用到的动态代理模式。
首先要知道它为什么要使用动态代理,可以观察到当执行mybatis的代码时,他总能打印出一些执行语句的记录,这就像spring里的aop(通过动态代理实现),是通过动态代理实现的,如下类都是mybatis对动态代理日志类的实现:

可以通过下图看出底下的四个logger都继承了基类logger,并且都实现了invocationhandler:

这样整个动态代理框架就出来了。
例如ConnectionLogger:

/**    Copyright ${license.git.copyrightYears} the original author or authors.**    Licensed under the Apache License, Version 2.0 (the "License");*    you may not use this file except in compliance with the License.*    You may obtain a copy of the License at**       http://www.apache.org/licenses/LICENSE-2.0**    Unless required by applicable law or agreed to in writing, software*    distributed under the License is distributed on an "AS IS" BASIS,*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.*    See the License for the specific language governing permissions and*    limitations under the License.*/
package org.apache.ibatis.logging.jdbc;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;import org.apache.ibatis.logging.Log;
import org.apache.ibatis.reflection.ExceptionUtil;/*** Connection proxy to add logging.** @author Clinton Begin* @author Eduardo Macarron**/
//负责打印连接信息和sql语句并创建一个preparestatmentLogger
public final class ConnectionLogger extends BaseJdbcLogger implements InvocationHandler {//真正的连接对象private final Connection connection;private ConnectionLogger(Connection conn, Log statementLog, int queryStack) {super(statementLog, queryStack);this.connection = conn;}@Overridepublic Object invoke(Object proxy, Method method, Object[] params)throws Throwable {try {//如果是object自己的方法则忽略if (Object.class.equals(method.getDeclaringClass())) {return method.invoke(this, params);}//增强跟数据库打交道的方法if ("prepareStatement".equals(method.getName()) || "prepareCall".equals(method.getName())) {if (isDebugEnabled()) {debug(" Preparing: " + removeExtraWhitespace((String) params[0]), true);}PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);//创建一个PreparedStatementLogger,具有相关的preparedstatement的打印stmt = PreparedStatementLogger.newInstance(stmt, statementLog, queryStack);return stmt;} else if ("createStatement".equals(method.getName())) {Statement stmt = (Statement) method.invoke(connection, params);stmt = StatementLogger.newInstance(stmt, statementLog, queryStack);return stmt;} else {return method.invoke(connection, params);}} catch (Throwable t) {throw ExceptionUtil.unwrapThrowable(t);}}/*** Creates a logging version of a connection.** @param conn*          the original connection* @param statementLog*          the statement log* @param queryStack*          the query stack* @return the connection with logging*/public static Connection newInstance(Connection conn, Log statementLog, int queryStack) {InvocationHandler handler = new ConnectionLogger(conn, statementLog, queryStack);ClassLoader cl = Connection.class.getClassLoader();return (Connection) Proxy.newProxyInstance(cl, new Class[]{Connection.class}, handler);}/*** return the wrapped connection.** @return the connection*/public Connection getConnection() {return connection;}}

很明显的可以看见增强逻辑。

mybatis里的日志动态代理相关推荐

  1. Mybatis DAO开发--Mapper动态代理开发方式

    Mybatis DAO开发–Mapper动态代理开发方式 第一步:jar包 创建lib目录,引入相应的jar包,本节课用到的案例引入的jar包就是spring整合mybatis要用到的全部jar包. ...

  2. Mybatis源码学习-动态代理

    Mybatis源码学习-动态代理 binding包下面是mybatis的mapper动态代理 // Mybatis官方手册建议通过mapper对象访问mybatis,因为使用mapper看起来更优雅 ...

  3. 【MyBatis笔记】06-Mapper动态代理

    Mppaer 动态代理 创建 Mapper 工程 定义接口的要求 测试类 Mapper 中参数传递 单个参数 多个参数 @param命名参数 多个参数封装成 Map 多个参数之 POJO 参数处理源码 ...

  4. mybatis 自定义函数_JDK动态代理一定要有代理对象吗?请你结合Mybatis回答

    动态代理 有一段时间没有写文章了, 主要是回想起这两年多的时间,多多少少,每个知识点差不多都有写到了, 一时也想不起什么新鲜的知识分享给大家.今天写动态代理,主要是在看Mybatis源码时,发现真的是 ...

  5. mybatis里的日志实现顺序

    在mybatis的logFactory里,可以清楚地看见加载顺序: 细看tryImplementation方法,可以看见先判断构造器是否为空,没有的话才利用反射去创建: 在每一个方法里又会有一个子方法 ...

  6. 【Java】Mybatis mapper动态代理方式

    前言 我们在使用Mybatis的时候,获取需要执行的SQL语句的时候,都是通过调用xml文件来获取,例如:User user = (User) sqlSession.selectOne("c ...

  7. 动态加载laydate 失效_Java对象的内存布局+反射的原理+动态代理+ 并发和锁+文末彩蛋...

    # 一行代码是怎么运行的 首先,java代码会被编译成字节码,字节码就是java虚拟机定义的一种编码格式,需要java虚拟机才能够解析,java虚拟机需要将字节码转换成机器码才能在cpu上执行. 我们 ...

  8. java 委托_动态代理:Java开发必学

    一句话概括:java 动态代理通过反射机制,可在不修改原代码的情况下添加新的功能,应用于多种场景,简单.实用.灵活,是 java 开发必学知识,本文将对动态代理使用进行详细介绍. 1. 引言 最近开发 ...

  9. 4种实例 advice aop_Java动态代理在Spring的应用:AOP编程与动态代理知识

    认真写文章,用心做分享.公众号:Java耕耘者 文章都会在里面更新,整理的资料也会放在里面. 关于代理模式的话题有很多,在开发中经常用到的应该是静态代理模式,能很好的去耦合. 动态代理是代理模式的另外 ...

最新文章

  1. CLR via C#(第3版):.net中的定时器整理总结
  2. 如何在C中为一个数组分配空间?
  3. 湘潭大学计算机学院调剂,湘潭大学2018年硕士研究生调剂信息公告
  4. mysql什么隔离级别最好_面试必问的 Mysql 四种隔离级别,看完吊打面试官
  5. boost::mp11::mp_contains相关用法的测试程序
  6. 通过自定义注解与aop统一存储操作记录
  7. 微软发布Azure Pipelines,开源项目可无限制使用CI/CD
  8. insert自动跳过存在数据_轻松入门mongo 数据库
  9. 大学生就业新神器 网络电话“通”职场
  10. 在vs2005中遇到的调试问题以及解决办法
  11. 软件开发常用的四种模式
  12. (六)我的JavaScript系列:更好的JavaScript之CoffeeScript
  13. 牛逼!这届WWDC依旧展现了那个让你无法复制的苹果!
  14. 通过API接口快速根据关键词获取拼多多商品列表
  15. Codeforces Problemset
  16. 支付宝官方支付接口申请配置教程(如何开通支付宝支付接口)
  17. python性能分析与优化
  18. word插入标题之后自动跳到下一页怎么解决?
  19. 蚂蚁金服入职考试_阿里巴巴蚂蚁金服面试通过,多久给offer?
  20. 2020年第十五届全国大学生智能汽车竞赛技术报告

热门文章

  1. Java黑皮书课后题第9章:9.2(Stock类)遵照9.2节中Cirlce类的例子,设计一个名为Stock的类
  2. Java黑皮书课后题第6章:*6.20(计算一个字符串中字母的个数)编写一个方法,使用下面的方法体计算字符串中的字母个数。编写一个测试程序,提示用户输入字符串,然后显示字符串中的字母个数
  3. C语言学习之1到5的乘积1到N的乘积
  4. ios 开发证书导出p12文件_开发者在上传企业签名的应用到后,做到如下几点
  5. Winform控件拖动
  6. Vue子组件与父组件之间的通信
  7. HTML5 Audio标签API整理(三)
  8. Intellij Idea上传本地项目到Git
  9. MemoryStream 反序列化的报错问题
  10. 209. Minimum Size Subarray Sum 长度最小的子数组