• JCL 和 SLF4J


    常见的日志实现:JUL、log4j、logback、log4j2
    常见的日志门面 :JCL、slf4j
    出现顺序 :log4j -->JUL-->JCL--> slf4j --> logback --> log4j2

    JCL

    JCL简介
    全称为Jakarta Commons Logging,是Apache提供的一个通用日志API。
    用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的jul, common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库。
    当然,common-logging内部有一个Simple logger的简单实现,但是功能很弱。所以使用common-logging,通常都是配合着log4j以及其他日志框架来使用。
    使用它的好处就是,代码依赖是common-logging而非log4j的API, 避免了和具体的日志API直接耦合,在有必要时,可以更改日志实现的第三方库。
    JCL 有两个基本的抽象类:
    Log:日志记录器
    LogFactory:日志工厂(负责创建Log实例)

    先导入依赖

    1. <groupId>commons-logging</groupId>
    2. <artifactId>commons-logging</artifactId>
    3. <version>1.2</version>
    4. </dependency>
    5. <dependency>
    6. <groupId>junit</groupId>
    7. <artifactId>junit</artifactId>
    8. <version>4.12</version>
    9. </dependency>
    1. public class JCLTest01 {
    2. @Test
    3. public void test01(){
    4. /*
    5. 我们暂时没有导入第三方的日志框架,例如log4j
    6. 默认的情况下,会使用JUL日志框架做日志的记录操作
    7. JCL使用原则:
    8. 如果有log4j,优先使用log4j
    9. 如果没有任何第三方日志框架的时候,我们使用的就是JUL
    10. */
    11. Log log = LogFactory.getLog(JCLTest01.class);
    12. log.info("info信息");
    13. }
    14. }

    总结:
        默认情况使用的是JUL,但是在集成了log4j环境后,使用的又是log4j
        通过测试观察,虽然日志框架发生了变化,但是代码完全没有改变

    日志门面技术的好处:
        门面技术是面向接口的开发,不再依赖具体的实现类,减少代码的耦合性
        可以根据实际需求,灵活的切换日志框架
        统一的API,方便开发者学习和使用
        统一的配置管理便于项目日志的维护工作

     

    SLF4J

    简单日志门面(Simple Logging Facade For Java) SLF4J主要是为了给Java日志访问提供一套标准、规范的API框架,其主要意义在于提供接口,具体的实现可以交由其他日志框架,例如log4j和logback等。 当然slf4j自己也提供了功能较为简单的实现,但是一般很少用到。对于一般的Java项目而言,日志框架会选择slf4j-api作为门面,配上具体的实现框架(log4j、logback等),中间使用桥接器完成桥接。所以我们可以得出SLF4J最重要的两个功能就是对于日志框架的绑定以及日志框架的桥接。
    官方网站: https://www.slf4j.org/

    导入依赖

    1. <dependency>
    2. <groupId>org.slf4j</groupId>
    3. <artifactId>slf4j-api</artifactId>
    4. <version>1.7.25</version>
    5. </dependency>
    6. <!--slf4j 自带的简单日志实现 -->
    7. <dependency>
    8. <groupId>org.slf4j</groupId>
    9. <artifactId>slf4j-simple</artifactId>
    10. <version>1.7.25</version>
    11. </dependency>

    SLF4J对日志的级别划分
    trace、debug、info、warn、error五个级别
    trace:日志追踪信息
    debug:日志详细信息
    info:日志的关键信息 默认打印级别
    warn:日志警告信息
    error:日志错误信息

    在没有任何其他日志实现框架集成的基础之上
    slf4j使用的就是自带的框架slf4j-simple
    slf4j-simple也必须以单独依赖的形式导入进来

    <!--<dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.25</version>
    </dependency>-->

    1. @Test
    2. public void test03(){
    3. Logger logger = LoggerFactory.getLogger(SLF4JTest01.class);
    4. String name = "zs";
    5. int age = 23;
    6. //logger.info("学生信息-姓名:"+name+";年龄:"+age);
    7. //logger.info("学生信息-姓名:{},年龄:{}",new Object[]{name,age});
    8. logger.info("学生信息-姓名:{},年龄:{}",name,age);
    9. try {
    10. int n = 1/0;
    11. } catch (ClassNotFoundException e) {
    12. //打印栈追踪信息
    13. //e.printStackTrace();
    14. //e是引用类型对象,不能根前面的{}做有效的字符串拼接
    15. //logger.info("具体错误是:{}",e);//错误写法
    16. //我们不用加{},直接后面加上异常对象e即可
    17. logger.info("具体错误是:",e);
    18. }
    19. }

    SLF4J日志门面,共有3种情况对日志实现进行绑定
    1.在没有绑定任何日志实现的基础之上,日志是不能够绑定实现任何功能的
        值得大家注意的是,通过我们刚刚的演示,slf4j-simple是slf4j官方提供的
        使用的时候,也是需要导入依赖,自动绑定到slf4j门面上
        如果不导入,slf4j 核心依赖是不提供任何实现的
    2.logback和simple(包括nop)
        都是slf4j门面时间线后面提供的日志实现,所以API完全遵循slf4j进行的设计
        那么我们只需要导入想要使用的日志实现依赖,即可与slf4j无缝衔接
        值得一提的是nop虽然也划分到实现中了,但是他是指不实现日志记录(后续课程)
    3.log4j和JUL(这两个需要导入适配器)
        都是slf4j门面时间线前面的日志实现,所以API不遵循slf4j进行设计
        通过适配桥接的技术,完成的与日志门面的衔接

            <!-- 导入log4j适配器依赖 -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.25</version>
            </dependency>

            <!-- 导入jul适配器依赖 -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-jdk14</artifactId>
                <version>1.7.25</version>
            </dependency>


    在真实生产环境中,slf4j只绑定一个日志实现框架就可以了
    绑定多个,默认使用导入依赖的第一个,而且可能会产生没有必要的警告信息

                需求:
                    假设我们项目一直以来使用的是log4j日志框架
                    但是随着技术和需求的更新换代
                    log4j已然不能够满足我们系统的需求
                    我们现在就需要将系统中的日志实现重构为 slf4j+logback的组合
                    在不触碰java源代码的情况下,将这个问题给解决掉


                    此时需要将日志替换为slf4j+logback
                    我们既然不用log4j了,就将log4j去除
                    将slf4j日志门面和logback的日志实现依赖加入进来
                    这样做,没有了log4j环境的支持,编译报错

                    这个时候就需要使用桥接器来做这个需求了
                    桥接器解决的是项目中日志的重构问题,当前系统中存在之前的日志API,
                    可以通过桥接转换到slf4j的实现

                    桥接器的使用步骤:
                    1.去除之前旧的日志框架依赖
                        <dependency>
                            <groupId>log4j</groupId>
                            <artifactId>log4j</artifactId>
                            <version>1.2.17</version>
                        </dependency>
                    2.添加slf4j提供的桥接组件
                        log4j相关的桥接器
                        <dependency>
                            <groupId>org.slf4j</groupId>
                            <artifactId>log4j-over-slf4j</artifactId>
                            <version>1.7.25</version>
                        </dependency>
                      桥接器加入后,代码编译就不报错了

     

     

    注意:
        在桥接器加入之后,适配器就没有必要加入了
        桥接器和适配器不能同时导入依赖
        桥接器如果配置在适配器的上方,则运行报错,不同同时出现
        桥接器如果配置在适配器的下方,则不会执行桥接器,没有任何的意义

  • 相关阅读:
    渲染引擎的资源加载优化
    【竞技宝】DOTA2-梦幻联赛S22:AR命悬一线 XG确定晋级淘汰赛
    测试人员Bug书写规范
    只需要改造一下实体类,以后再也不用写SQL了
    数学术语之源——平凡(trivial)与非平凡(nontrivial)
    基于python和django旅游管理系统
    flutter Widget index
    使用 Fiddler 抓包PC微信小程序
    Redis 主从
    Java开发:注解Annotation
  • 原文地址:https://blog.csdn.net/weixin_45729272/article/details/125549796