SLF4J与Spring集成实战:替代JCL并绑定Log4j

devtools/2025/2/13 4:19:56/

在Java开发中,日志框架的选择和集成一直是一个重要的环节。SLF4J(Simple Logging Facade for Java)作为一个流行的日志门面框架,提供了简单而强大的日志抽象层。与JCL(Jakarta Commons Logging)相比,SLF4J在性能、灵活性和扩展性上都有显著优势。本文将通过一个实际的Spring项目示例,展示如何使用SLF4J替代JCL,并将其绑定到Log4j作为日志实现。
Maven依赖配置
在Spring项目中,我们通常会使用Maven来管理依赖。为了使用SLF4J替代JCL,我们需要在pom.xml中进行以下配置:
xml复制


org.springframework
spring-core
4.3.10.RELEASE


commons-logging
commons-logging




org.springframework
spring-context
4.3.10.RELEASE


org.slf4j
slf4j-log4j12
1.8.0-alpha2


org.slf4j
jcl-over-slf4j
1.8.0-alpha2


在上述配置中,我们通过排除了commons-logging依赖,这样可以避免Spring内部日志代码直接使用JCL。取而代之的是jcl-over-slf4j,它提供了一个与JCL完全兼容的替代实现,但底层日志调用会被重定向到SLF4J。此外,slf4j-log4j12依赖将SLF4J绑定到Log4j实现,并且会自动引入Log4j依赖,无需单独添加。
创建使用SLF4J的Bean
接下来,我们创建一个简单的Bean类,使用SLF4J进行日志记录:
java复制
package com.logicbig.example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyBean {
private static final Logger log = LoggerFactory.getLogger(MyBean.class);

public void doSomething() {log.info("doing something");
}

}
在上述代码中,我们通过LoggerFactory.getLogger(MyBean.class)获取了一个与MyBean类绑定的日志实例,并在doSomething方法中记录了一条INFO级别的日志。
配置Log4j
为了使Log4j能够正确工作,我们需要在src/main/resources目录下创建一个log4j.properties文件,配置日志输出格式和目标:
properties复制
log4j.rootCategory=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yy-MM-dd HH:mm:ss:SSS} %5p %t %c{2}:%L - %m%n
上述配置将日志输出到控制台,并定义了详细的日志格式,包括时间戳、日志级别、线程名、类名、行号和日志消息。
主类与Spring上下文
最后,我们创建一个主类,使用Spring的注解配置来初始化上下文并调用MyBean的doSomething方法:
java复制
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

@Configuration
public class ExampleMain {
@Bean
public MyBean myBean() {
return new MyBean();
}

public static void main(String[] args) {AnnotationConfigApplicationContext context =new AnnotationConfigApplicationContext(ExampleMain.class);MyBean bean = context.getBean(MyBean.class);bean.doSomething();context.close();
}

}
在上述代码中,我们通过@Configuration注解定义了一个Spring配置类,并通过@Bean注解声明了一个MyBean的Bean。在main方法中,我们创建了一个AnnotationConfigApplicationContext实例,从上下文中获取MyBean实例并调用其doSomething方法。
输出结果
运行上述程序后,控制台将输出类似以下的日志:
复制
17-09-07 15:58:21:405 INFO main annotation.AnnotationConfigApplicationContext:583 - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@ea30797: startup date [Thu Sep 07 15:58:21 CDT 2017]; root of context hierarchy
17-09-07 15:58:21:567 INFO main example.MyBean:10 - doing something
从输出结果可以看出,Spring的日志和MyBean的日志都通过SLF4J和Log4j正确输出,并且格式一致。
总结
通过上述示例,我们展示了如何在Spring项目中使用SLF4J替代JCL,并将其绑定到Log4j。这种方法不仅可以避免JCL带来的潜在问题,还能充分利用SLF4J的灵活性和Log4j的强大功能。希望本文能帮助你在实际项目中更好地管理和优化日志系统。


http://www.ppmy.cn/devtools/158376.html

相关文章

TCP/IP参考模型和网络协议

由于国防部担心他们一些重要的主机、路由器和互联网关可能会突然崩溃,所以网络必须实现的另一目标是网络不受子网硬件损失的影响,已经建立的会话不会被取消,而且整个体系结构必须相当灵活。 TCP/IP是一组用于实现网络互连的通信协议。Interne…

【KOA】01-专栏介绍及学习计划(后续项目实战结合Vue3)

前言 关于node的知识,前面的文章介绍了express框架,并且做了一个专栏。 Express专栏 最近了解到node的koa框架也是比较常用、实用,因此在接下来会介绍相关知识,编写相关代码案例,写成博客文章,整理成一个…

Spring实现AOP功能的原理:代理模式(JDK动态代理与CGLIB字节码生成技术代理)的理解

JDK 动态代理和 CGLIB 代理是 Java 中两种常见的动态代理技术。它们的核心作用是 在运行时生成代理对象,用于增强原始对象的功能(如 AOP 切面编程、拦截方法调用等)。 ① JDK 动态代理 JDK 动态代理基于 java.lang.reflect.Proxy 和 Invocat…

SQL最佳实践(笔记)

写在前面: 之前baeldung的Java Weekly Reviews里面推荐了一篇关于SQL优化的文章,正好最近在学习数据库相关知识,记一些学习笔记 原文地址:SQL Best Practices Every Java Engineer Must Know 1. 使用索引 使用索引…

java-LinkedList源码详解

前言&#xff1a; LinkedList 是 Java 中另一个常用的集合类&#xff0c;它基于双向链表实现&#xff0c;支持高效的插入和删除操作&#xff0c;但随机访问性能较差 类定义和成员变量&#xff1a; public class LinkedList<E>extends AbstractSequentialList<E>…

zsh: command not found: conda

场景描述 在 Linux 服务器上使用 zsh 时&#xff0c;如果出现 zsh: command not found: conda 错误&#xff0c;说明你的系统未正确配置 conda 命令&#xff0c;或者你尚未安装 Anaconda/Miniconda。 解决方案 确保已安装 Anaconda 或 Miniconda conda 是 Anaconda 或 Minico…

java后端开发day14--之前练习的总结和思考

1.感受 这两天学点儿新的就直接上手打代码&#xff0c;真的是累死个人。我唯一的感受就是&#xff0c;课听完了&#xff0c;代码也跟着打完了&#xff08;是的&#xff0c;跟着打的&#xff0c;没自己打&#xff09;&#xff0c;感觉自己脑袋里乱乱的&#xff0c;对代码的分区…

【05】RUST常用的集合函数宏类型

文章目录 常用集合VecStringHashMap 宏打印 类型Option<T> 常用集合 Vec 堆上连续内存vector可能出现扩容&#xff0c;把老元素copy到内存新位置 因此不允许let first &v[0];作用域内调用v.push(4); // 定义 let v: Vec<i32> Vec::new(); let v vec![1,…