/** 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語句并創建一個preparestatmentLoggerpublicfinalclassConnectionLoggerextendsBaseJdbcLoggerimplementsInvocationHandler{//真正的連接對象privatefinal Connection connection;privateConnectionLogger(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;}elseif("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*/publicstatic Connection newInstance(Connection conn, Log statementLog,int queryStack){InvocationHandler handler =newConnectionLogger(conn, statementLog, queryStack);ClassLoader cl = Connection.class.getClassLoader();return(Connection) Proxy.newProxyInstance(cl,newClass[]{Connection.class}, handler);}/*** return the wrapped connection.** @return the connection*/public Connection getConnection(){return connection;}}