`
qiuguo0205
  • 浏览: 240952 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

从iBATIS Hibernate 去日志依赖 看 模块化Java

阅读更多

前几天看了一篇文章,名为模块化Java简介 。模块化的思想就是去耦合,这样在升级或者维护的时候都会方便一些,这样的道理大家都知道,但是怎样在实现中完成这一点呢。


作者在“类库也是模块”这一节中介绍了“类库毫无疑问也是模块。对于类库来讲,可能没有一个单一接口与之通信,但往往却有‘public ’ API(可能被用到)和‘private ’ package(文档中说明了其用途)。此外,它们也有自己依赖的类库(比如JMXJMS )。这将引起自动依赖管理器引入许多并非必须的类库:以Log4J-1.2.15 为例,引入了超过10个依赖类库(包括javax.mail和javax.jms),尽管这些类库中有不少对于使用Log4J的程序来说根本不需要。 即要做到,某些情况下,一个模块的依赖可以是可选的。”

 

虽然文章的其他部分看不太懂,但是这个内容倒是可以考察的。Hibernate和iBATIS[注:这里使用的是iBATIS2作为示例]中的日志模块都是与他们的类库模块分开的,那么他们是怎么做到的呢?

 

Hibernate用的是Apache Commons Logging 开源工具做到的,而iBATIS用的其实就是自己实现的一个简化的Apache Commons Logging:

首先使用定义一个通用的接口,自己在程序中使用的就是这样一个接口:

package com.ibatis.common.logging;

public interface Log {
  boolean isDebugEnabled();
  void error(String s, Throwable e);
  void error(String s);
  public void debug(String s);
  public void warn(String s);
}

 


LogFactory 是用来生成这个Log接口实现的工厂类

package com.ibatis.common.logging;

import java.lang.reflect.Constructor;
import com.ibatis.common.resources.Resources;

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



Log4jImpl 是Log 接口的一个实例类,用来实现与log4j的交互

package com.ibatis.common.logging.log4j;

import org.apache.log4j.Logger;

public class Log4jImpl implements com.ibatis.common.logging.Log {

  private Logger log;

  public Log4jImpl(Class clazz) {
     log = Logger.getLogger(clazz);
  }

  public boolean isDebugEnabled() {
    return log.isDebugEnabled();
  }

  public void error(String s, Throwable e) {
    log.error(s, e);
  }
  ......
}
 


注意到这里最终还是使用了log4j的接口 import org.apache.log4j.Logger;所以说明该jar包在编译的时候还是需要log4j的,但是在实际使用的时候log4j不是必须的,这样就成功去掉了依赖。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics