日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

mybatis里的日志动态代理

發布時間:2024/4/18 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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里的日志动态代理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。