- 浏览: 126897 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
hengyunabc:
非常感谢!终于解决这问题了
解决wine xshell之后无法键盘无法响应 -
01jiangwei01:
你的那个xmlns:ns1="com.eshangr ...
flex动态树(xml) -
yuanye218:
遇到chanelset是null这个问题的时候,正好看到了您的 ...
flex中chanel的小小研究
Commons-log + log4j 这黄金搭档一直以来都让我们很省心,很好的完成了日志的需求。但是随着技术的变更和对性能的追求,slf4j 和 logback 这对后起之秀的到来好像打破了原本很平静的日志系统,频繁的出现包冲突...
和平的日子不在了,让我们一起来看看究竟发生了什么...
首先看看这些个包,特别是slf4j引入后就引入了一大堆包之后就有点懵了。
为什么commons-logging和jcl-over-slf4j会有冲突呢?看一下它们的类结构
很清晰的可以看到jcl-over-slf4j 重写了 commons-logging...
还有slf4j-api的实现呢,同样看类:
其实就这么简单,往往看了代码之后才发现错误是这么显而易见。。。
顺着研究,继续看一下slf4j的源码及流程
1.测试类
package com.taobao.wuzhong.log; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * DESC: * * Copyright: Copyright 2011 m.taobao.com * * @author wuzhong@taobao.com * @time 2011-4-6 下午03:42:11 * @version 1.0 **/ public class LogTest { // Logback tries to find a file called logback.groovy in the classpath. // If no such file is found, logback tries to find a file called // logback-test.xml in the classpath. // If no such file is found, it checks for the file logback.xml in the // classpath.. // If neither file is found, logback configures itself automatically using // the BasicConfigurator which will cause logging output to be directed to // the console. @Test public void test() { //commons-logging的方式获取 Log log = LogFactory.getLog(LogTest.class); //slf4j直接的方式获取,推荐用这个 Logger log2 = LoggerFactory.getLogger(LogTest.class); log.debug("eeeeee {} {} {}"); log2.debug("{} {} {}", new String[] { "a", "b", "c" }); } }
logFactory.getLog 会调用内部静态变量 Slf4jLogFactory.getInstance方法,如下:
public Log getInstance(String name) throws LogConfigurationException {
Log instance = null; // protect against concurrent access of loggerMap synchronized (this) { instance = (Log) loggerMap.get(name); if (instance == null) { Logger logger = LoggerFactory.getLogger(name); //slf4j的方式,代理过去了 if(logger instanceof LocationAwareLogger) { instance = new SLF4JLocationAwareLog((LocationAwareLogger) logger); //包装了一层,做适配 } else { instance = new SLF4JLog(logger); } loggerMap.put(name, instance); } } return (instance); }
loggerFactory 会调用getILoggerFactory().getlOgger()
LoggerFactory.java public static ILoggerFactory getILoggerFactory() { if (INITIALIZATION_STATE == UNINITIALIZED) { INITIALIZATION_STATE = ONGOING_INITILIZATION; performInitialization(); } switch (INITIALIZATION_STATE) { case SUCCESSFUL_INITILIZATION: return getSingleton().getLoggerFactory(); case FAILED_INITILIZATION: throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG); case ONGOING_INITILIZATION: // support re-entrant behavior. // See also http://bugzilla.slf4j.org/show_bug.cgi?id=106 return TEMP_FACTORY; } throw new IllegalStateException("Unreachable code"); } private final static void performInitialization() { bind(); versionSanityCheck(); singleImplementationSanityCheck(); }
这里的bind很关键,这里动态的绑定了slf4j-api的实现机制
static { SINGLETON.init(); } /** * Package access for testing purposes. */ void init() { try { try { new ContextInitializer(defaultLoggerContext).autoConfig(); } catch (JoranException je) { Util.reportFailure("Failed to auto configure default logger context", je); } StatusPrinter.printInCaseOfErrorsOrWarnings(defaultLoggerContext); contextSelectorBinder.init(defaultLoggerContext, KEY); initialized = true; } catch (Throwable t) { // we should never get here Util.reportFailure("Failed to instantiate [" + LoggerContext.class.getName() + "]", t); } }
获取配置信息初始化
autoConfig …. public URL findURLOfDefaultConfigurationFile(boolean updateStatus) { ClassLoader myClassLoader = Loader.getClassLoaderOfObject(this); URL url = findConfigFileURLFromSystemProperties(myClassLoader, updateStatus); if (url != null) { return url; } url = Loader.getResource(TEST_AUTOCONFIG_FILE, myClassLoader); if (updateStatus) { statusOnResourceSearch(TEST_AUTOCONFIG_FILE, myClassLoader, url); } if (url != null) { return url; } url = Loader.getResource(AUTOCONFIG_FILE, myClassLoader); if (updateStatus) { statusOnResourceSearch(AUTOCONFIG_FILE, myClassLoader, url); } return url; } public void autoConfig() throws JoranException { StatusListenerConfigHelper.installIfAsked(loggerContext); URL url = findURLOfDefaultConfigurationFile(true); if (url != null) { configureByResource(url); } else { BasicConfigurator.configure(loggerContext); } }
最后画张流程图总结下,^_^
总结: log框架应该很好的诠释了 facade , adapter , 实现上还是比较简单的,很好的做到了接口和实现的分离,对今后的代码组织有一定的启发
发表评论
-
nodejs学习
2012-04-11 09:49 1773简介 Node.js是一个使用javascrip ... -
代码回顾-request
2011-10-21 23:09 1514webx3中(wdetail)处理淘客的一个pipeli ... -
正则表达式入门学习笔记
2011-01-13 14:19 925在线测试: http://gskinner.com/Re ... -
eclipse 开发环境搭建
2010-11-28 18:37 1009eclipse3.5 开发环境搭建1.subclipse ht ... -
了解jvm
2010-09-27 14:12 1017读《深入java虚拟机》的一点体会,综合了很多网友的分享 -
maven setting实践之修改jdk默认版本
2010-05-12 11:26 5182<?xml version="1.0&qu ... -
java中文字符完整性判断
2010-04-22 14:04 1477前提: 英文字符在utf8编码下是1个字符 中文的ut ... -
axis2 command line and code generation
2009-08-19 08:32 18481.ant脚本 WSDL2JAVA <!-- ... -
springsecurity2 自定义filter实现
2009-06-02 15:14 2691配置 <global-method-security ... -
J2ee开发常见问题及解决方法
2009-05-28 10:36 12161.Mysql连接数据库出现java/sql/SQLClien ... -
spring security
2009-05-18 20:10 1613转载: Acegi提供了多种身份验证方式(表单验证,CAS ... -
转发和重定向的深入理解
2009-02-23 14:29 957他们的调用分别如下例: request.getRequestD ... -
同步、异步、阻塞和非阻塞的概念
2008-11-28 12:20 1701同步、异步、阻塞和非阻塞的概念【zz】 由 zhanjun 在 ... -
spring通过.PropertyPlaceholderConfigurer读取配置文件
2008-11-13 14:14 5726properties配置文件 hibernate.show ... -
java基础回顾2(j2se)
2008-11-12 15:38 741.hashtable 同步 实现directory ha ... -
java基础回顾(j2se)
2008-11-11 16:56 841.数组 定义如:int[] a []中间不能有参数 ...
相关推荐
**Log4j日志框架详解** Log4j是Apache组织开发的一个开源的日志记录框架,广泛应用于Java应用程序中。作为一款强大的日志处理工具,它提供了灵活的日志配置,允许开发者根据需求调整日志级别、格式和输出位置,极大...
Log4Qt是Qt框架下的一款日志记录库,它基于流行的Java日志库log4j设计,为C++开发者提供了一套强大、灵活的日志处理机制。本文将深入探讨Log4Qt日志管理的核心概念、功能特性以及如何在实际项目中有效应用。 一、...
"采用JDK实现的日志框架"是一个基于Java Development Kit(JDK)1.4中的`java.util.logging`包构建的日志系统,它旨在提供与流行的Log4j框架类似的灵活性和功能。 `java.util.logging`是Java平台的标准日志API,自...
此外,C++标准库并没有提供内置的日志框架,但在实际开发中,很多开发者会使用第三方库,如Glog、spdlog等,它们提供了更强大、更灵活的功能,例如异步日志处理、自定义格式化和日志过滤等。 总之,通过理解日志...
【SSH+Maven+Bootstrap视频教程】第18章主要讲解了如何测试并应用Log4j日志框架,这是Java开发中的一个关键组件,尤其在系统监控、调试和错误跟踪方面发挥着重要作用。Log4j是Apache软件基金会的一个开放源代码项目...
Log4j是一个广泛使用的Java日志框架,在服务器端和桌面应用中非常常见。不过,Log4j原生并不直接支持Android平台,因为它依赖于一些Android系统不包含的库。但有一些开发者社区提供了对Android的适配版本,让Log4j...
Log4net是一个强大的日志管理框架,广泛应用于各种软件项目中,主要用于诊断和修复配置问题。该框架提供了丰富的功能,确保开发人员能够有效地记录、管理和分析应用中的日志信息。 **日志分级功能**是Log4net的核心...
SSM框架log4j.properties日志打印必备包SSM框架log4j.properties日志打印必备包SSM框架log4j.properties日志打印必备包SSM框架log4j.properties日志打印必备包
`LogDemo`则可能是一个示例应用,展示了如何在实际项目中使用这个自定义的日志框架。 总之,自定义日志框架是Android开发中的一个重要实践,它能提供更高效、安全、可定制的日志管理方案。通过阅读和学习提供的源码...
本文将深入探讨Java中的log日志组件,包括JDK内置的日志(jdkLog)、Apache的Commons Logging(commonLog)以及流行的log4j。了解这些组件的特点和用法,将提升你对Java日志处理的理解。 首先,我们来看看JDK内置的...
此压缩包提供的资源是针对Tomcat8及其以下版本的日志管理解决方案,主要涉及Log4j这个流行的Java日志框架。下面将详细介绍如何在Tomcat8中替换或更新Log4j来记录日志。 首先,让我们了解一下Log4j。Log4j是Apache...
标题中的“日志框架学习之一:commons-logging+log4j”揭示了本文将探讨的是在Java开发中常用的两个日志处理工具——Apache Commons Logging和Log4j。这两个框架是日志记录的基础,广泛应用于各种Java应用程序,为...
**log4cplus** 是一个基于C++的开源日志框架,它的设计灵感来源于Java社区中的log4j,旨在提供一种高效、灵活且易于使用的日志记录解决方案。这个框架允许开发者在C++程序中方便地记录调试信息,帮助追踪代码问题、...
这就是自定义日志框架的意义所在。下面,我们将深入探讨如何在Android中创建一个自定义日志框架。 首先,理解Android系统内置的`Log`类。`Log`类提供了`d()`, `i()`, `w()`, `e()`等方法,用于输出不同级别的日志,...
在IT行业中,日志(log)是至...综上所述,"log日志的实现"涉及了如何在Struts和iBatis等框架中配置和使用日志,以及如何通过最佳实践来提升日志的价值。通过对日志的合理管理,可以大大提高开发效率和系统的可维护性。
这些框架各有特点,Log4j是早期广泛使用的日志框架,Logback由Log4j的作者设计,提供了更好的性能和配置灵活性;SLF4J是一个抽象层,允许开发者选择底层的日志实现;JUL则是Java内置的日志系统。 2. **SLF4J与...
本文将深入探讨"Log日志配置"的相关知识点,包括日志的重要性、常用日志框架、配置细节以及如何通过日志记录运行结果和参数。 一、日志的重要性 1. 错误排查:当程序出现异常时,日志记录可以帮助开发者快速定位...
**Java日志框架Log4j详解** 在Java编程中,日志记录是不可或缺的一部分,它帮助开发者追踪程序运行状态,定位错误,以及进行性能分析。Log4j是Apache组织开发的一个开源日志框架,它是Java日志处理领域的经典工具,...
标题"Android-AndroidLog日志打印输出到文件方便查看和上传到服务器"所描述的,就是一种将Android应用的日志信息写入到本地文件的方法,以便后续分析或上传到远程服务器。这个方法能够帮助开发者在无法直接访问设备...
例如,在SpringBoot+Dubbo项目中,可能会出现log4j和logback的冲突,因为Dubbo依赖了zkclient,而zkclient又依赖了log4j,这样如果项目中还有其他日志框架存在并有使用,就会导致多套共存。解决方案是使用slf4j+...