为啥使用 SLF4J 而不是 Log4J 来做 Java 日志

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥使用 SLF4J 而不是 Log4J 来做 Java 日志相关的知识,希望对你有一定的参考价值。

在代码中编写日志记录语句使用SLF4J的主要动机是让程序独立于任何特定的日志记录库,这些日志记录库可能需要与现在配置不同的配置,而且还会引入更多令人头疼的维护问题。然而除了这个之外,SLF4J API还有一个让您使用SLF4J而不是用长期感兴趣的 Log4j 更让人信服的功能,就是占位符功能,在代码中用来表示。占位符功能与 String的format()方法中的%s非常相似,因为它在运行时刻才提取所提供的真正的字符串。这不仅缩减了代码中的许多字符串连接,而且减少了创建String对象所需要的资源。即便在生产环境日志级别比如DEBUG和INFO级别的字符串连接可能不需要的时候,仍然可以起到同样的效果。由于字符串是不可更改的 ,而它们是在字符串池中创建的,这些字符串使用了堆内存 ,当应用在生产环境中运行在ERROR级别的时候,字符串在大多数情况下就不是必须的,比如DEBUG语句里的字符串就不是必须的。通过使用SLF4J可以延迟字符串的创建到运行时刻,这意味着只有在需要字符串的时候才创建它。如果已经使用了log4j,那么您已经熟悉把调试语句放入if()条件内的工作场景,而SLF4J占位符功能比log4j更适合这种场景。
下面是用Log4j时的做法,当然这并不好玩而且它增加了不必要的公式化的代码,减少了代码的可读性。

1
2
3

if (logger.isDebugEnabled())
logger.debug("Processing trade with id: " + id + " symbol: " + symbol);


如果使用SLF4J,可以使用更简洁的格式达到同样的效果,如下:

logger.debug("Processing trade with id: and symbol : ", id, symbol);

在SLF4J中,我们不需要进行字符串拼接,不会导致使用临时字符串带来的消耗。相反,我们使用带占位符的模板消息来记录日志信息,并提供实际值作为参数。在为日志信息产生最终的字符串之前,该方法会检查是否开启了特定的日志级别,这不仅降低了内存占用,而且预先减少了执行字符串拼接所消耗的CPU时间。下面的SLF4J日志方法的代码,来自于slf4j-log4j12-1.6.1.jar包里的Log4j的适配器类

Log4jLoggerAdapter.
public void debug(String format, Object arg1, Object arg2) if (logger.isDebugEnabled()) FormattingTuple ft = MessageFormatter.format(format, arg1, arg2); logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable());

日志也会对应用程序的性能产生压力,大家通常宣扬的是只在生产环境中才强制记录日志。
参考技术A 因为他不知道,通常项目中都是用log4J,就像Spring struts2等等这些开源框架,都是用log4j的

为啥不用动画 GIF 而不是动画 CSS sprite?

【中文标题】为啥不用动画 GIF 而不是动画 CSS sprite?【英文标题】:Why not animated GIF instead of animated CSS sprites?为什么不用动画 GIF 而不是动画 CSS sprite? 【发布时间】:2012-04-28 11:58:39 【问题描述】:

在最近的趋势中,我看到人们使用 JavaScript 而不是动画 GIF 来制作 CSS sprite 动画?

例如:

http://www.google.com/doodles/eadweard-j-muybridges-182nd-birthday(事实上,谷歌在其他涂鸦中也使用了这种技术) https://everyme.com/(“我”标志) 还有更多...

这只是为了展示或试验技术,还是从中获得任何好处。我有兴趣知道好处,如果有的话。 我问的原因是我无法弄清楚,因为在这两种情况下我们都需要生成中间帧(主要使用补间技术)。

【问题讨论】:

以下是 Apple 在 iPhone 5 页面上的详细介绍 - docs.google.com/document/… 【参考方案1】:

控制

您无法控制 GIF 动画。你无法启动它们,也无法阻止它们。他们只是在加载后立即制作动画。

使用精灵,您可以控制动画。您可以启动、停止和响应浏览器事件,平移动画。例如,Google Doodles 通常会在您单击它们时激活。

9gag 中有一个漂亮的 GIF 控制系统。您可以通过将它们附加到 DOM 来启动它们,并通过删除它们并使用预先生成的“第一帧视图”交换它们来停止它们。但这只是 GIF 的范围。

独立实例

当您加载同一个 GIF 的多个实例时,所有这些实例都会在页面上使用同一个图像并同时移动。如果你有一排跳舞的独角兽 GIF,它们会同时跳舞。花样跳舞!

但是对于精灵,即使您使用相同的图像,动画也依赖于底层脚本。因此,如果一个 sprite 由一个脚本制作动画,而另一个 sprite 由另一个脚本制作动画,则这两个动画可以独立运行,并且彼此不同。

这使您无需创建另一个 GIF,而且由于您只是更改脚本,因此很容易修改。

确保流畅的动画

动画 GIF 仅在加载时进行动画处理,当互联网速度较慢时,动画会冻结,直到加载更多图像。

相比之下,精灵的优点是您可以预先加载它们,确保预先加载所有图像。这可确保用于该动画的资源在动画之前已加载,以确保其动画尽可能流畅。

但是,GIF 是静止图像。您可以从 DOM 中动态加载它们并在将它们附加到 DOM 之前侦听加载事件。

部分渲染

使用 PNG sprite,您可以在动画中制作“部分”,将动画场景分解为部分。例如,当一个角色静止不动,但手臂在挥动时。您不需要为整个角色或整个场景设置动画。您可以将描绘角色身体精灵的元素置于“冻结”状态,而手臂是不同的动画元素。这节省了精灵表的空间和大小。 2012 年 Google 的母亲节涂鸦就是一个很好的例子。

相比之下,大多数时候,GIF 动画中的每一帧都是完整的图像,并且无论其中的任何内容是否移动都会产生动画效果。帧数越多,GIF 的大小就越大。

GIF 无法缩放

GIF 用于图标。与 PNG 和 JPG 相比,GIF 的文件大小与图像大小的比例并没有那么好。

【讨论】:

您所说的 GIF 中的每一帧都是图像并不是 100% 正确的。 GIF 格式允许使用各种背景清除选项进行部分帧更新。【参考方案2】:

除了梦想家约瑟夫的回答...

据我所知,或者至少过去是这样,GIF 文件不是真彩色,这是使用 JPG/PNG 作为 css sprite 的另一个原因。

【讨论】:

以上是关于为啥使用 SLF4J 而不是 Log4J 来做 Java 日志的主要内容,如果未能解决你的问题,请参考以下文章

为什么使用 SLF4J 而不是 Log4J 来做 Java 日志

为啥要使用SLF4J而不是Log4J

为啥要使用SLF4J而不是Log4J

为啥要使用SLF4J而不是Log4J

日志记录工具

log4j.xml 为什么要使用SLF4J而不是Log4J