mybatis里的日志动态代理
上一篇博客说到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里的日志动态代理相关推荐
- Mybatis DAO开发--Mapper动态代理开发方式
Mybatis DAO开发–Mapper动态代理开发方式 第一步:jar包 创建lib目录,引入相应的jar包,本节课用到的案例引入的jar包就是spring整合mybatis要用到的全部jar包. ...
- Mybatis源码学习-动态代理
Mybatis源码学习-动态代理 binding包下面是mybatis的mapper动态代理 // Mybatis官方手册建议通过mapper对象访问mybatis,因为使用mapper看起来更优雅 ...
- 【MyBatis笔记】06-Mapper动态代理
Mppaer 动态代理 创建 Mapper 工程 定义接口的要求 测试类 Mapper 中参数传递 单个参数 多个参数 @param命名参数 多个参数封装成 Map 多个参数之 POJO 参数处理源码 ...
- mybatis 自定义函数_JDK动态代理一定要有代理对象吗?请你结合Mybatis回答
动态代理 有一段时间没有写文章了, 主要是回想起这两年多的时间,多多少少,每个知识点差不多都有写到了, 一时也想不起什么新鲜的知识分享给大家.今天写动态代理,主要是在看Mybatis源码时,发现真的是 ...
- mybatis里的日志实现顺序
在mybatis的logFactory里,可以清楚地看见加载顺序: 细看tryImplementation方法,可以看见先判断构造器是否为空,没有的话才利用反射去创建: 在每一个方法里又会有一个子方法 ...
- 【Java】Mybatis mapper动态代理方式
前言 我们在使用Mybatis的时候,获取需要执行的SQL语句的时候,都是通过调用xml文件来获取,例如:User user = (User) sqlSession.selectOne("c ...
- 动态加载laydate 失效_Java对象的内存布局+反射的原理+动态代理+ 并发和锁+文末彩蛋...
# 一行代码是怎么运行的 首先,java代码会被编译成字节码,字节码就是java虚拟机定义的一种编码格式,需要java虚拟机才能够解析,java虚拟机需要将字节码转换成机器码才能在cpu上执行. 我们 ...
- java 委托_动态代理:Java开发必学
一句话概括:java 动态代理通过反射机制,可在不修改原代码的情况下添加新的功能,应用于多种场景,简单.实用.灵活,是 java 开发必学知识,本文将对动态代理使用进行详细介绍. 1. 引言 最近开发 ...
- 4种实例 advice aop_Java动态代理在Spring的应用:AOP编程与动态代理知识
认真写文章,用心做分享.公众号:Java耕耘者 文章都会在里面更新,整理的资料也会放在里面. 关于代理模式的话题有很多,在开发中经常用到的应该是静态代理模式,能很好的去耦合. 动态代理是代理模式的另外 ...
最新文章
- CLR via C#(第3版):.net中的定时器整理总结
- 如何在C中为一个数组分配空间?
- 湘潭大学计算机学院调剂,湘潭大学2018年硕士研究生调剂信息公告
- mysql什么隔离级别最好_面试必问的 Mysql 四种隔离级别,看完吊打面试官
- boost::mp11::mp_contains相关用法的测试程序
- 通过自定义注解与aop统一存储操作记录
- 微软发布Azure Pipelines,开源项目可无限制使用CI/CD
- insert自动跳过存在数据_轻松入门mongo 数据库
- 大学生就业新神器 网络电话“通”职场
- 在vs2005中遇到的调试问题以及解决办法
- 软件开发常用的四种模式
- (六)我的JavaScript系列:更好的JavaScript之CoffeeScript
- 牛逼!这届WWDC依旧展现了那个让你无法复制的苹果!
- 通过API接口快速根据关键词获取拼多多商品列表
- Codeforces Problemset
- 支付宝官方支付接口申请配置教程(如何开通支付宝支付接口)
- python性能分析与优化
- word插入标题之后自动跳到下一页怎么解决?
- 蚂蚁金服入职考试_阿里巴巴蚂蚁金服面试通过,多久给offer?
- 2020年第十五届全国大学生智能汽车竞赛技术报告
热门文章
- Java黑皮书课后题第9章:9.2(Stock类)遵照9.2节中Cirlce类的例子,设计一个名为Stock的类
- Java黑皮书课后题第6章:*6.20(计算一个字符串中字母的个数)编写一个方法,使用下面的方法体计算字符串中的字母个数。编写一个测试程序,提示用户输入字符串,然后显示字符串中的字母个数
- C语言学习之1到5的乘积1到N的乘积
- ios 开发证书导出p12文件_开发者在上传企业签名的应用到后,做到如下几点
- Winform控件拖动
- Vue子组件与父组件之间的通信
- HTML5 Audio标签API整理(三)
- Intellij Idea上传本地项目到Git
- MemoryStream 反序列化的报错问题
- 209. Minimum Size Subarray Sum 长度最小的子数组