看了ibatis的日志机制。其中ibatis支持JakartaCommonsLogging、 Jdk14LoggingImpl、Log4j和默认日志即什么都不输出。下面看一下日志的UML图
[img]http://dl.iteye.com/upload/attachment/255642/81f4aac2-1051-3912-b0a5-f14fb3ad0e7c.jpg[/img]
ibatis在选择要使用哪一个日志机制时,使用了java反射技术.
看com.ibatis.common.logging.LogFactory类的源码:
public class LogFactory {
private static Constructor logConstructor;
static {
tryImplementation("org.apache.commons.logging.LogFactory", "com.ibatis.common.logging.jakarta.JakartaCommonsLoggingImpl");
tryImplementation("org.apache.log4j.Logger", "com.ibatis.common.logging.log4j.Log4jImpl");
tryImplementation("java.util.logging.Logger", "com.ibatis.common.logging.jdk14.Jdk14LoggingImpl");
tryImplementation("java.lang.Object", "com.ibatis.common.logging.nologging.NoLoggingImpl");
}
private static void tryImplementation(String testClassName, String implClassName) {
if (logConstructor == null) {
try {
Resources.classForName(testClassName);
Class implClass = Resources.classForName(implClassName);
logConstructor = implClass.getConstructor(new Class[]{Class.class});
} catch (Throwable t) {
}
}
}
public static Log getLog(Class aClass) {
try {
return (Log)logConstructor.newInstance(new Object[]{aClass});
} catch (Throwable t) {
throw new RuntimeException("Error creating logger for class " + aClass + ". Cause: " + t, t);
}
}
public static synchronized void selectLog4JLogging() {
try {
Resources.classForName("org.apache.log4j.Logger");
Class implClass = Resources.classForName("com.ibatis.common.logging.log4j.Log4jImpl");
logConstructor = implClass.getConstructor(new Class[]{Class.class});
} catch (Throwable t) {
}
}
public static synchronized void selectJavaLogging() {
try {
Resources.classForName("java.util.logging.Logger");
Class implClass = Resources.classForName("com.ibatis.common.logging.jdk14.Jdk14LoggingImpl");
logConstructor = implClass.getConstructor(new Class[]{Class.class});
} catch (Throwable t) {
}
}
}
系统默认只给我们实现了两种日志。
其实我们可以实现自己的日志机制只要你实现com.ibatis.common.logging.Log接口就行,
并在com.ibatis.common.logging.LogFactory添加相应的tryImplementation(String testClassName, String implClassName)和添加类方法public static synchronized void yourmethod().其实都可以参照源代码写。
ibatis在日志这方面做的很好!个人觉得。
当程序要使用有关数据库的日志记录时,如connection连接、preparestatement语句记录等等。其实是用日志log.isDebugEnabled()判断是否使用日志记录。通过返回相关connection的代理实现日志记录。
如
if (connectionLog.isDebugEnabled()) {
connection = ConnectionLogProxy.newInstance(connection);
}
ConnectionLogProxy源码如下:
public class ConnectionLogProxy extends BaseLogProxy implements InvocationHandler {
private static final Log log = LogFactory.getLog(Connection.class);
private Connection connection;
private ConnectionLogProxy(Connection conn) {
super();
this.connection = conn;
if (log.isDebugEnabled()) {
log.debug("{conn-" + id + "} Connection");
}
}
public Object invoke(Object proxy, Method method, Object[] params)
throws Throwable {
try {
if ("prepareStatement".equals(method.getName())) {
if (log.isDebugEnabled()) {
log.debug("{conn-" + id + "} Preparing Statement: " + removeBreakingWhitespace((String) params[0]));
}
PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
stmt = PreparedStatementLogProxy.newInstance(stmt, (String) params[0]);
return stmt;
} else if ("prepareCall".equals(method.getName())) {
if (log.isDebugEnabled()) {
log.debug("{conn-" + id + "} Preparing Call: " + removeBreakingWhitespace((String) params[0]));
}
PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
stmt = PreparedStatementLogProxy.newInstance(stmt, (String) params[0]);
return stmt;
} else if ("createStatement".equals(method.getName())) {
Statement stmt = (Statement) method.invoke(connection, params);
stmt = StatementLogProxy.newInstance(stmt);
return stmt;
} else {
return method.invoke(connection, params);
}
} catch (Throwable t) {
Throwable t1 = ClassInfo.unwrapThrowable(t);
log.error("Error calling Connection." + method.getName() + ':', t1);
throw t1;
}
}
/**
* Creates a logging version of a connection
* @param conn - the original connection
* @return - the connection with logging
*/
public static Connection newInstance(Connection conn) {
InvocationHandler handler = new ConnectionLogProxy(conn);
ClassLoader cl = Connection.class.getClassLoader();
return (Connection) Proxy.newProxyInstance(cl, new Class[]{Connection.class}, handler);
}
}
[img]http://dl.iteye.com/upload/attachment/255645/e0cdba00-542b-3813-8fa9-3047f714af20.jpg[/img]
[img]http://dl.iteye.com/upload/attachment/255642/81f4aac2-1051-3912-b0a5-f14fb3ad0e7c.jpg[/img]
ibatis在选择要使用哪一个日志机制时,使用了java反射技术.
看com.ibatis.common.logging.LogFactory类的源码:
public class LogFactory {
private static Constructor logConstructor;
static {
tryImplementation("org.apache.commons.logging.LogFactory", "com.ibatis.common.logging.jakarta.JakartaCommonsLoggingImpl");
tryImplementation("org.apache.log4j.Logger", "com.ibatis.common.logging.log4j.Log4jImpl");
tryImplementation("java.util.logging.Logger", "com.ibatis.common.logging.jdk14.Jdk14LoggingImpl");
tryImplementation("java.lang.Object", "com.ibatis.common.logging.nologging.NoLoggingImpl");
}
private static void tryImplementation(String testClassName, String implClassName) {
if (logConstructor == null) {
try {
Resources.classForName(testClassName);
Class implClass = Resources.classForName(implClassName);
logConstructor = implClass.getConstructor(new Class[]{Class.class});
} catch (Throwable t) {
}
}
}
public static Log getLog(Class aClass) {
try {
return (Log)logConstructor.newInstance(new Object[]{aClass});
} catch (Throwable t) {
throw new RuntimeException("Error creating logger for class " + aClass + ". Cause: " + t, t);
}
}
public static synchronized void selectLog4JLogging() {
try {
Resources.classForName("org.apache.log4j.Logger");
Class implClass = Resources.classForName("com.ibatis.common.logging.log4j.Log4jImpl");
logConstructor = implClass.getConstructor(new Class[]{Class.class});
} catch (Throwable t) {
}
}
public static synchronized void selectJavaLogging() {
try {
Resources.classForName("java.util.logging.Logger");
Class implClass = Resources.classForName("com.ibatis.common.logging.jdk14.Jdk14LoggingImpl");
logConstructor = implClass.getConstructor(new Class[]{Class.class});
} catch (Throwable t) {
}
}
}
系统默认只给我们实现了两种日志。
其实我们可以实现自己的日志机制只要你实现com.ibatis.common.logging.Log接口就行,
并在com.ibatis.common.logging.LogFactory添加相应的tryImplementation(String testClassName, String implClassName)和添加类方法public static synchronized void yourmethod().其实都可以参照源代码写。
ibatis在日志这方面做的很好!个人觉得。
当程序要使用有关数据库的日志记录时,如connection连接、preparestatement语句记录等等。其实是用日志log.isDebugEnabled()判断是否使用日志记录。通过返回相关connection的代理实现日志记录。
如
if (connectionLog.isDebugEnabled()) {
connection = ConnectionLogProxy.newInstance(connection);
}
ConnectionLogProxy源码如下:
public class ConnectionLogProxy extends BaseLogProxy implements InvocationHandler {
private static final Log log = LogFactory.getLog(Connection.class);
private Connection connection;
private ConnectionLogProxy(Connection conn) {
super();
this.connection = conn;
if (log.isDebugEnabled()) {
log.debug("{conn-" + id + "} Connection");
}
}
public Object invoke(Object proxy, Method method, Object[] params)
throws Throwable {
try {
if ("prepareStatement".equals(method.getName())) {
if (log.isDebugEnabled()) {
log.debug("{conn-" + id + "} Preparing Statement: " + removeBreakingWhitespace((String) params[0]));
}
PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
stmt = PreparedStatementLogProxy.newInstance(stmt, (String) params[0]);
return stmt;
} else if ("prepareCall".equals(method.getName())) {
if (log.isDebugEnabled()) {
log.debug("{conn-" + id + "} Preparing Call: " + removeBreakingWhitespace((String) params[0]));
}
PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
stmt = PreparedStatementLogProxy.newInstance(stmt, (String) params[0]);
return stmt;
} else if ("createStatement".equals(method.getName())) {
Statement stmt = (Statement) method.invoke(connection, params);
stmt = StatementLogProxy.newInstance(stmt);
return stmt;
} else {
return method.invoke(connection, params);
}
} catch (Throwable t) {
Throwable t1 = ClassInfo.unwrapThrowable(t);
log.error("Error calling Connection." + method.getName() + ':', t1);
throw t1;
}
}
/**
* Creates a logging version of a connection
* @param conn - the original connection
* @return - the connection with logging
*/
public static Connection newInstance(Connection conn) {
InvocationHandler handler = new ConnectionLogProxy(conn);
ClassLoader cl = Connection.class.getClassLoader();
return (Connection) Proxy.newProxyInstance(cl, new Class[]{Connection.class}, handler);
}
}
[img]http://dl.iteye.com/upload/attachment/255645/e0cdba00-542b-3813-8fa9-3047f714af20.jpg[/img]