I 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);
    }
  }

}

实现一个二叉排序树的迭代器

Sat 01 March 2014 by XiaomengZhao

二叉搜索树的中序遍历是有序的。在该篇文章中,我们实现了一个二叉搜索树的迭代器,每次调用该迭代器的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 ...
read more

树的前中后的非递归遍历

Sat 01 March 2014 by XiaomengZhao

树的前序遍历

没从栈中取出一个元素,就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 ...
read more

实现一个二叉排序树的迭代器

Sat 01 March 2014 by XiaomengZhao

二叉搜索树的中序遍历是有序的。在该篇文章中,我们实现了一个二叉搜索树的迭代器,每次调用该迭代器的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 ...
read more

JavaScript中的onload事件

Sat 01 February 2014 by XiaomengZhao

首先,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 ...
read more
Fork me on GitHub