How can Mybatis know its logger?
Tue 02 June 2015 by XiaomengZhaoI always have a question that how Mybatis know that I use Log4j as logger rather than other loggers. Here is the answer. Mybatis just try every logger :)
/**
* Copyright 2009-2015 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;
import java.lang.reflect.Constructor;
/**
* @author Clinton Begin
* @author Eduardo Macarron
*/
public final class LogFactory {
/**
* Marker to be used by logging implementations that support markers
*/
public static final String MARKER = "MYBATIS";
private static Constructor<? extends Log> logConstructor;
static {
tryImplementation(new Runnable() {
@Override
public void run() {
useSlf4jLogging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useCommonsLogging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useLog4J2Logging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useLog4JLogging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useJdkLogging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useNoLogging();
}
});
}
private LogFactory() {
// disable construction
}
public static Log getLog(Class<?> aClass) {
return getLog(aClass.getName());
}
public static Log getLog(String logger) {
try {
return logConstructor.newInstance(new Object[] { logger });
} catch (Throwable t) {
throw new LogException("Error creating logger for logger " + logger + ". Cause: " + t, t);
}
}
public static synchronized void useCustomLogging(Class<? extends Log> clazz) {
setImplementation(clazz);
}
public static synchronized void useSlf4jLogging() {
setImplementation(org.apache.ibatis.logging.slf4j.Slf4jImpl.class);
}
public static synchronized void useCommonsLogging() {
setImplementation(org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl.class);
}
public static synchronized void useLog4JLogging() {
setImplementation(org.apache.ibatis.logging.log4j.Log4jImpl.class);
}
public static synchronized void useLog4J2Logging() {
setImplementation(org.apache.ibatis.logging.log4j2.Log4j2Impl.class);
}
public static synchronized void useJdkLogging() {
setImplementation(org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl.class);
}
public static synchronized void useStdOutLogging() {
setImplementation(org.apache.ibatis.logging.stdout.StdOutImpl.class);
}
public static synchronized void useNoLogging() {
setImplementation(org.apache.ibatis.logging.nologging.NoLoggingImpl.class);
}
private static void tryImplementation(Runnable runnable) {
if (logConstructor == null) {
try {
runnable.run();
} catch (Throwable t) {
// ignore
}
}
}
private static void setImplementation(Class<? extends Log> implClass) {
try {
Constructor<? extends Log> candidate = implClass.getConstructor(new Class[] { String.class });
Log log = candidate.newInstance(new Object[] { LogFactory.class.getName() });
if (log.isDebugEnabled()) {
log.debug("Logging initialized using '" + implClass + "' adapter.");
}
logConstructor = candidate;
} catch (Throwable t) {
throw new LogException("Error setting Log implementation. Cause: " + t, t);
}
}
}
实现一个二叉排序树的迭代器
二叉搜索树的中序遍历是有序的。在该篇文章中,我们实现了一个二叉搜索树的迭代器,每次调用该迭代器的next方法可以返回有序的数字。迭代器的好处是,可以对调用者屏蔽底层数据结构的复杂性,调用者不用考虑底层数据存储是用数组实现,还是链表实现,或者是二叉搜索树实现。
Java迭代器需要实现以下接口:
public interface BinaryTreeIterator {
// Are there other nodes to see in this traversal?
boolean hasNext();
// Return the value of the key in the next node in the
// traversal, and advance the position of the iterator.
TreeNode next();
}
下面就是我们实现了这以借口。对树的中序遍历进行了一些修改。
public class ...
树的前中后的非递归遍历
树的前序遍历
没从栈中取出一个元素,就visit该元素,然后先压栈它的右元素,然后压栈它的左元素。因为栈是先进后出,左元素肯定要比右元素先出来。
public class PreOrderTraversal {
public List<Integer> preorderTraversal(TreeNode root) {
// write your code here
ArrayList<Integer> result = new ArrayList<Integer>();
if(root == null)
return null;
Stack<TreeNode> s = new Stack<TreeNode>();
s.push(root);
while(s.size() != 0){
TreeNode p = s.pop();
s.add ...
实现一个二叉排序树的迭代器
二叉搜索树的中序遍历是有序的。在该篇文章中,我们实现了一个二叉搜索树的迭代器,每次调用该迭代器的next方法可以返回有序的数字。迭代器的好处是,可以对调用者屏蔽底层数据结构的复杂性,调用者不用考虑底层数据存储是用数组实现,还是链表实现,或者是二叉搜索树实现。
Java迭代器需要实现以下接口:
public interface BinaryTreeIterator {
// Are there other nodes to see in this traversal?
boolean hasNext();
// Return the value of the key in the next node in the
// traversal, and advance the position of the iterator.
TreeNode next();
}
下面就是我们实现了这以借口。对树的中序遍历进行了一些修改。
public class ...
JavaScript中的onload事件
首先,onload属于HTML DOM Events,而HTML DOM Events的定义如下:
Event对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。 HTML DOM事件通常与处理函数绑定在一起,允许Javascript为HTML文档中的元素注册不同的事件处理函数,处理函数不会在事件发生之前被执行。
而onload事件是在一张页面或一副图像完成后加载。可以用在<body>
, <frame>
, <frameset>
,<iframe>
, <img>
, <input type="image">
, <link>
, <script>
, <style>
这些标签中。但是绝大多数情况下,onload会用在<body>
元素中,一旦一个网页全部加载好(包括图片, 脚本文件, CSS样式表,etc),就执行事件处理函数,所以一般onload处理函数都是最后执行的。
你可以这样写:
<!DOCTYPE html>
<html>
<head>
<script>
function myFunction ...