LOG4J是一个非常优秀的开源日志组件,今天对它的源代码进行的一点学习,收获如下:
 
1、调用方法:
  // 初始化一个日志对象
  private static Logger log = Logger.getLogger(MyLog.class);
  // 调用该对象进行日志记录
  log.debug("good job");
 
2、设置系统属性的方法:
    // JAVA 中设置系统属性的方法
    // 1:
    System.setProperty("log.key1", "true");
    System.out.println(System.getProperty("log.key1"));
    // 2:在虚拟机运行参数中添加 -log.key2=goodjobkey
    System.out.println(System.getProperty("log.key2"));
 
 
3、内部日志类(记录组件内部的日志信息):
package logtest;

import java.io.IOException;

public class InnerLog {
  public static final String DEBUG_KEY = "mylog.debug";
  private static final String DEBUG_PREFIX = "mylog:DEBUG ";
  private static final String ERR_PREFIX = "mylog:ERROR ";

  protected static boolean debugEnabled = false;
  protected static boolean quietMode = false;

  static {
    String key = System.getProperty(DEBUG_KEY);
    debugEnabled = "true".equalsIgnoreCase(key);
  }

  public static void setDebugEnabled(boolean debugEnabled) {
    InnerLog.debugEnabled = debugEnabled;
  }

  public static void setQuietMode(boolean quietMode) {
    InnerLog.quietMode = quietMode;
  }

  public static void debug(String msg) {
    if (debugEnabled && !quietMode) {
      System.out.println(DEBUG_PREFIX + msg);
    }
  }

  public static void debug(String msg, Throwable t) {
    if (debugEnabled && !quietMode) {
      System.out.println(DEBUG_PREFIX + msg);
      if (t != null) {
        t.printStackTrace(System.out);
      }
    }
  }

  public static void error(String msg) {
    if (!quietMode) {
      System.err.println(ERR_PREFIX + msg);
    }
  }

  public static void error(String msg, Throwable t) {
    if (!quietMode) {
      System.err.println(msg);
      if (t != null) {
        t.printStackTrace(System.err);
      }
    }
  }

  public static void main(String[] args) {
    // 内部日志类
    Throwable t = new IOException("IOException");
    System.out.println(System.getProperty(InnerLog.DEBUG_KEY));
    InnerLog.debug("debug inner", t);
    InnerLog.error("error msg", t);
    InnerLog.setDebugEnabled(true);
    // 输出DEBUG信息
    InnerLog.debug("debug inner2", t);
    InnerLog.error("error msg2", t);
    InnerLog.setQuietMode(true);
    // 什么都不输出(安静模式下)
    InnerLog.debug("debug inner3", t);
    InnerLog.error("error msg3", t);
  }
}
 
设置了虚拟机参数(-Dmylog.debug=true)的输出:
true
mylog:DEBUG debug inner
java.io.IOException: IOException
  at logtest.MyLog.main(MyLog.java:21)
mylog:DEBUG debug inner2
java.io.IOException: IOException
  at logtest.MyLog.main(MyLog.java:21)
error msg
java.io.IOException: IOException
  at logtest.MyLog.main(MyLog.java:21)
error msg2
java.io.IOException: IOException
  at logtest.MyLog.main(MyLog.java:21)
没有设置mylog.debug参数的输出:
null
mylog:DEBUG debug inner2
java.io.IOException: IOException
  at logtest.MyLog.main(MyLog.java:21)
error msg
java.io.IOException: IOException
  at logtest.MyLog.main(MyLog.java:21)
error msg2
java.io.IOException: IOException
 
4-、加载properties文件及解析${}型参数:
package logtest;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class PropConfig {
  private static final String CFG_FILE = "mylog.properties";
  protected static Properties props;
  static String DELIM_START = "${";
  static char DELIM_STOP = '}';
  static int DELIM_START_LEN = 2;
  static int DELIM_STOP_LEN = 1;

  static {
    props = new Properties();
    InputStream input = null;
    try {
      String fileName = PropConfig.class.getClassLoader().getResource(CFG_FILE).getFile();
      input = new FileInputStream(new File(fileName));
      props.load(input);
      input.close();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if (input != null) {
        try {
          input.close();
        } catch (IOException e) {
        }
      }
    }
    // props.list(System.out);
  }

  public static String substVal(String str) {
    if (str == null) {
      return "";
    }
    StringBuffer sbuf = new StringBuffer(128);
    int i = 0;
    int j = 0;
    int k = 0;
    while (true) {
      j = str.indexOf(DELIM_START, i);
      if (j == -1) {
        if (i == 0) {
          return str;
        } else {
          return sbuf.append(str.substring(i, str.length())).toString();
        }
      } else {
        sbuf.append(str.substring(i, j));
        k = str.indexOf(DELIM_STOP, j);
        if (k == -1) {
          throw new IllegalArgumentException("有开始符号没有结束符号!");
        } else {
          j += DELIM_START_LEN;
          String key = str.substring(j, k);
          String replaceStr = props.getProperty(key);
          // 如果没有替换项,则保持空
          if (replaceStr != null) {
            sbuf.append(substVal(replaceStr));
          }
          i = k + DELIM_STOP_LEN;
        }

      }
    }
  }

  public static void main(String[] args) {
    String str = "good job ${username},${datetime}!";
    props.setProperty("username", "kink");
    props.setProperty("datetime", "2009-4-14 ${time}");
    props.setProperty("time", "15:07");
    System.out.println(substVal(str));
  }
}
输出结果如下:
good job kink,2009-4-14 15:07!
 
5、利用反射机制创建对象并实现属性的赋值:
首先创建一个简单的VO对象:
package logtest;

public class User {
  private String name;
  private long id;
  private int age;
  private boolean bool;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public long getId() {
    return id;
  }

  public void setId(long id) {
    this.id = id;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  public boolean isBool() {
    return bool;
  }

  public void setBool(boolean bool) {
    this.bool = bool;
  }

  public String toString() {
    return "name:" + name + " id:" + id + " age:" + age + " bool:" + bool;
  }
}
 
实现对上面User类的创建及属性的赋值:
package logtest;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.Properties;

public class Cla***eflex {
  public Object getObject(String className, Properties props) throws Exception {
    // 获得类对象
    Class clazz = Class.forName(className);
    // 取得BEAN信息
    BeanInfo bi = Introspector.getBeanInfo(clazz);
    // 获取属性描述
    PropertyDescriptor[] descs = bi.getPropertyDescriptors();
    Object obj = clazz.newInstance();
    for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
      String key = (String) e.nextElement();
      String value = props.getProperty(key);
      if (value != null) {
        key = Introspector.decapitalize(key);
        PropertyDescriptor desc = this.getPropertyDescriptor(key, descs);
        this.setProperty(obj, desc, key, value);
      }
    }
    return obj;
  }

  private PropertyDescriptor getPropertyDescriptor(String name, PropertyDescriptor[] descs) {
    for (int i = 0; i < descs.length; i++) {
      if (name.equals(descs[i].getName())) {
        return descs[i];
      }
    }
    return null;
  }

  private void setProperty(Object obj, PropertyDescriptor desc, String name, String value) {
    Method setter = desc.getWriteMethod();
    Class[] paramTypes = setter.getParameterTypes();
    Object arg = this.convertArg(value, paramTypes[0]);
    try {
      setter.invoke(obj, new Object[] { arg });
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  protected Object convertArg(String val, Class type) {
    if (val == null)
      return null;
    String v = val.trim();
    if (String.class.isAssignableFrom(type)) {
      return val;
    } else if (Integer.TYPE.isAssignableFrom(type)) {
      return new Integer(v);
    } else if (Long.TYPE.isAssignableFrom(type)) {
      return new Long(v);
    } else if (Boolean.TYPE.isAssignableFrom(type)) {
      if ("true".equalsIgnoreCase(v)) {
        return Boolean.TRUE;
      } else if ("false".equalsIgnoreCase(v)) {
        return Boolean.FALSE;
      }
    }
    return null;
  }

  public static void main(String[] args) {
    Cla***eflex cr = new Cla***eflex();
    Properties props = new Properties();
    props.setProperty("name", "kink");
    props.setProperty("Id", "20009");
    props.setProperty("age", "23");
    props.setProperty("bool", "true");

    User user = null;
    try {
      user = (User) cr.getObject(User.class.getName(), props);
    } catch (Exception e) {
      e.printStackTrace();
    }
    System.out.println(user);
  }
}
输出结果如下:
name:kink id:20009 age:23 bool:true