当前位置: 首页 > news >正文

日志门面技术

1.JCL

public abstract class LogFactory {public static Log getLog(Class clazz) throws LogConfigurationException {// 默认实现类为LogFactoryImplreturn getFactory().getInstance(clazz);}
}

利用LogFactoryImpl实例化具体的日志框架。其中,如果存在log4j依赖则选择Log4JLogger,Jdk14Logger是指JDK本身集成的JUL,否则使用JCL本身自带的日志实现之SimpleLog。

public class LogFactoryImpl extends LogFactory {protected Constructor logConstructor = null;private static final String[] classesToDiscover = {"org.apache.commons.logging.impl.Log4JLogger","org.apache.commons.logging.impl.Jdk14Logger","org.apache.commons.logging.impl.Jdk13LumberjackLogger","org.apache.commons.logging.impl.SimpleLog"}protected Log newInstance(String name) throws LogConfigurationException {Log instance;if (logConstructor == null) {instance = discoverLogImplementation(name);}else {Object params[] = { name };instance = (Log) logConstructor.newInstance(params);}if (logMethod != null) {Object params[] = { this };logMethod.invoke(instance, params);}return instance;}private Log discoverLogImplementation(String logCategory)throws LogConfigurationException {...for(int i=0; i<classesToDiscover.length && result == null; ++i) {result = createLogFromClass(classesToDiscover[i], logCategory, true);}return result;}private Log createLogFromClass(String logAdapterClassName,String logCategory,boolean affectState){Object[] params = { logCategory };Log logAdapter = null;Constructor constructor = null;Class logAdapterClass = null;ClassLoader currentCL = getBaseClassLoader();for(;;) {...Class  c = Class.forName(logAdapterClassName, true, currentCL);constructor = c.getConstructor(logConstructorSignature);Object o = constructor.newInstance(params);if (o instanceof Log) {logAdapterClass = c;logAdapter = (Log) o;break;}handleFlawedHierarchy(currentCL, c);if (currentCL == null) {break;}currentCL = getParentClassLoader(currentCL);}...return logAdapter;}
}

2.Slf4j

StaticLoggerBinder是存在于各种日志适配桥接相关的依赖中,并且在不同依赖中该类的全限定名都为:org.slf4j.impl.StaticLoggerBinder。

例如,slf4j-jdk14是Slf4j对JUL适配的相关依赖,在其包中的类StaticLoggerBinder引入jul相关的日志核心类JDK14LoggerFactory。

public class JDK14LoggerFactory implements ILoggerFactory {ConcurrentMap<String, Logger> loggerMap;public JDK14LoggerFactory() {java.util.logging.Logger.getLogger("");//获取JDK自带的日志框架实现}
}

slf4j-log4j12是Slf4j对log4j适配的相关依赖,在其包中的类StaticLoggerBinder引入log4j相关的日志核心类Log4jLoggerFactory。

public class Log4jLoggerFactory implements ILoggerFactory {ConcurrentMap<String, Logger> loggerMap;public Log4jLoggerFactory() {loggerMap = new ConcurrentHashMap<String, Logger>();// force log4j to initializeorg.apache.log4j.LogManager.getRootLogger();//获取log4j自带的日志框架实现}
}
public final class LoggerFactory {private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";public static Logger getLogger(String name) {ILoggerFactory iLoggerFactory = getILoggerFactory();return iLoggerFactory.getLogger(name);}public static ILoggerFactory getILoggerFactory() {if (INITIALIZATION_STATE == 0) {synchronized (LoggerFactory.class) {if (INITIALIZATION_STATE == 0) {INITIALIZATION_STATE = 1;performInitialization();}}}switch (INITIALIZATION_STATE) {case SUCCESSFUL_INITIALIZATION:return StaticLoggerBinder.getSingleton().getLoggerFactory();case NOP_FALLBACK_INITIALIZATION:return NOP_FALLBACK_FACTORY;case FAILED_INITIALIZATION:throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);case ONGOING_INITIALIZATION:return SUBST_FACTORY;}throw new IllegalStateException("Unreachable code");}private final static void performInitialization() {bind();}private final static void bind() {Set<URL> staticLoggerBinderPathSet = null;if (!isAndroid()) {staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);}// the next line does the bindingStaticLoggerBinder.getSingleton();INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;reportActualBinding(staticLoggerBinderPathSet);fixSubstituteLoggers();replayEvents();// release all resources in SUBST_FACTORYSUBST_FACTORY.clear();}static Set<URL> findPossibleStaticLoggerBinderPathSet() {Set<URL> staticLoggerBinderPathSet = new LinkedHashSet<URL>();ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader();Enumeration<URL> paths;//利用StaticLoggerBinder引入具体的日志框架if (loggerFactoryClassLoader == null) {paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);} else {paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH);}while (paths.hasMoreElements()) {URL path = paths.nextElement();staticLoggerBinderPathSet.add(path);}return staticLoggerBinderPathSet;}
}

3.SpringBoot默认日志类型

SpringBoot中是由包spring-boot-starter-logging提供的日志功能,该包下只是引入日志相关的门面技术以及具体的日志框架:logback-classic、log4j-to-slf4j、jul-to-slf4j。其中logback是完全实现了门面框架slf4j相关的API,所以可以与slf4j无缝衔接。但是log4j、jul其出现的时间都早于slf4j,所以其如果想利用门面技术slf4j时就需要相关的桥接技术,log4j-to-slf4j、jul-to-slf4j分别就是log4j、jul对应的桥接功能的实现者。

相关文章:

日志门面技术

1.JCL public abstract class LogFactory {public static Log getLog(Class clazz) throws LogConfigurationException {// 默认实现类为LogFactoryImplreturn getFactory().getInstance(clazz);} }利用LogFactoryImpl实例化具体的日志框架。其中&#xff0c;如果存在log4j依赖…...

机器人制作开源方案 | 管内检测维护机器人

一、作品简介 作者&#xff1a;李泽彬&#xff0c;李晋晟&#xff0c;杜张坤&#xff0c;禹馨雅 单位&#xff1a;运城学院 指导老师&#xff1a;薛晓峰 随着我国的社会主义市场经济的飞速发展和科学技术的革新&#xff0c;各行各业的发展越来越离不开信息化和网络化的…...

k8s存储卷

目录 1、emptyDir存储卷 2、hostPath存储卷 3、nfs共享存储卷 4、PVC 和 PV 4.1 PV和PVC之间的相互作用遵循这个生命周期&#xff1a; 4.2 PV的状态 4.3 一个PV从创建到销毁的具体流程如下&#xff1a; 静态PVC&#xff1a; 动态PVC 1、emptyDir存储卷 当Pod被分配给节…...

View 自定义 - 属性 xml

一、概念 在 xml 中为控件设置的属性。自定义属性名称如果使用系统已定义的&#xff0c;例如 textSize 会在编译时报错。 格式类型定义/使用 string 字符串 <attr name "myContent" format "color" /> android:myContent "Hello Word!&quo…...

2007-2022年全国各地级市金融机构网点数据

2007-2022年地级市金融机构网点数据 1、时间&#xff1a;2007-2022年 2、指标&#xff1a;行政区划代码、年份、城市名称、所属省份、银行网点数量、其中-政策性银行及国家开发银行营业网点占比、其中-商业银行营业网点数量占比、其中-农村金融机构营业网点数量占比 3、范围…...

OpenAI开发者大会掀起风暴:GPT模型价格狂降50%,应用商店即将亮相,AI技术将引爆全球!

OpenAI首届开发者大会召开了&#xff01; 关键信息&#xff1a; GPT-4升级版GPT-4 Turbo来了&#xff0c;上下文窗口达到128k&#xff0c;为GPT-4的4倍&#xff1b;OpenAI还降低了几乎所有模型的API使用价格&#xff0c;整体便宜了一半多&#xff1b;GPT-4系列的多模态能力向B…...

yo!这里是STL::unordered系列简单模拟实现

目录 前言 相关概念介绍 哈希概念 哈希冲突与哈希函数 闭散列 框架 核心函数 开散列 框架 核心函数 哈希表&#xff08;开散列&#xff09;的修改 迭代器实现 细节修改 unordered系列封装 后记 前言 我们之前了解过map和set知道&#xff0c;map、set的底层结构是…...

基础课25——业务流程分析

1.流程的定义&作用 业务流程是企业中一系列创造价值的活动的组合&#xff0c;它是企业运营的基础&#xff0c;也是企业提高效率、优化资源配置的重要手段。通过优化业务流程&#xff0c;企业可以更好地满足客户需求&#xff0c;提高客户满意度&#xff0c;同时也可以提高自…...

快速实现一个企业级域名 SSL 证书有效期监控巡检系统

Why 现在对于企业来说&#xff0c;HTTPS 已经不是可选项&#xff0c;已经成为一个必选项。HTTPS 协议采用 SSL 协议&#xff0c;采用公开密钥的技术&#xff0c;提供了一套 TCP/IP 传输层数据加密的机制。SSL 证书是一种遵守 SSL 协议的服务器数字证书&#xff0c;一般是由权威…...

[SSD综述 1.5] SSD 主控和固件核心功能详解(万字)

依公知及经验整理&#xff0c;原创保护&#xff0c;禁止转载。 1. 主控概述1.1 主控作用 2. 主控的硬件功能和实现2.1 主控处理器2.2 闪存、主机接口2.3 主控纠错2.4 断电保护 3 固件功能3.1 FTL3.2 预留空间(Over-provisioning)3.3 Trim3.4 写入放大(Write amplification)3.5 …...

Mybatis-Plus前后端分离多表联查模糊查询分页

数据准备 数据库配置: /*Navicat Premium Data TransferSource Server : localhost_3306Source Server Type : MySQLSource Server Version : 80100 (8.1.0)Source Host : localhost:3306Source Schema : test01Target Server Type : MySQLT…...

【Ruoyi管理后台】用户登录强制修改密码

近期有个需求&#xff0c;就是需要调整Ruoyi管理后台&#xff1a;用户如果三个月(长时间)未修改过密码&#xff0c;需要在登录时强制修改密码&#xff0c;否则不能登录系统。 一、后端项目调整 从需求来看&#xff0c;我们需要在用户表增加一个字段&#xff0c;用于标记用户最…...

计算机网络基础知识1

1、tcp三次握手&#xff1f; SYN&#xff0c;标志位&#xff0c;用于建立TCP连接的握手过程中的标志位。 ACK&#xff0c;确认位&#xff0c;用于说明整个包是确认报文。 TCP/IP协议是传输层的一个面向连接提供可靠安全的传输协议。第一次握手有客户端发起&#xff0c;客户端向…...

人机交互中的多/变尺度态势感知

人机交互是指在人与计算机之间进行信息交换和任务完成的过程中&#xff0c;通过各种界面和交互方式来实现人机之间的有效沟通和协作。多尺度上下文是人机交互中一个重要的概念&#xff0c;它指的是在不同层次或不同尺度的信息之间建立联系&#xff0c;以便更好地理解和处理信息…...

命名管道原理(和匿名管道的对比),mkfifo(命令行,函数),命名管道模拟实现代码+与多个子进程通信代码

目录 命名管道 引入 原理 和匿名管道的对比 使用 -- mkfifo 命令行指令 创建 文件类型p 使用 函数 函数原型 模拟实现 头文件 客户端代码 服务端代码 运行情况 模拟实现 -- 与多个子进程 介绍 服务端代码: 运行情况 命名管道 引入 匿名管道只能用于父子进程…...

pytest全局变量的使用

这里重新阐述下PageObject设计模式&#xff1a; PageObject设计模式是selenium自动化最成熟&#xff0c;最受欢迎的一种模式&#xff0c;这里用pytest同样适用 这里直接提供代码&#xff1a; 全局变量 conftest.py """ conftest.py 全局变量&#xff0c;主要实…...

FreeRTOS源码阅读笔记2--list.c

list.c中主要完成列表数据结构的操作&#xff0c;有列表和列表项的初始化、列表的插入和移除。 2.1列表初始化vListInitialise() 2.1.1函数原型 void vListInitialise( List_t * const pxList ) pxList&#xff1a;列表指针&#xff0c;指向要初始化的列表。 2.1.2函数框架…...

杂货铺 | citespace的使用

安装教程 【CiteSpace保姆级教程1】文献综述怎么写&#xff1f; &#x1f4da;数据下载 1. 新建文件夹 2. 数据下载 知网高级检索 数据选中导出 &#xff1a;一次500 导出后重命名为download_xxx.txt&#xff0c;放到input文件里 3. 数据转换 把output里的数据复制到data里…...

C++ 静态成员变量初始化规则

每一天一个小trick&#xff01;&#xff01; 为什么静态成员不能在类内初始化&#xff1f; 在C中&#xff0c;类的静态成员&#xff08;static member&#xff09;必须在类内声明&#xff0c;在类外初始化&#xff0c;像下面这样。 class A { private: static int count …...

Docker安装、卸载,以及各种操作

docker是一个软件&#xff0c;是一个运行与linux和windows上的软件&#xff0c;用于创建、管理和编排容器&#xff1b;docker平台就是一个软件集装箱化平台&#xff0c;是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中&#xf…...

深入理解 C 语言的内存管理

文章目录 引言内存管理的重要性C语言内存布局C语言内存管理堆和栈内存的区别和用途内存分配和释放的过程C语言动态内存分配的概念和原因malloc()、calloc() 和 realloc() 等函数的使用悬挂指针和野指针内存泄漏和如何避免结论 引言 C语言是充满力量且灵活的编程语言&#xff0…...

利用Caddy实现http反向代理

利用Caddy实现http反向代理 1 Caddy是什么 Caddy是一个开源的&#xff0c;使用Golang编写的&#xff0c;支持HTTP/2的Web服务端。它的一个显著特征就是默认启用HTTPS。 和nginx类似。 2 多个后端服务 假如现在有3个后端http服务&#xff1a;分别在启动在 app1 http://10…...

【Qt之QVariant】使用

介绍 QVariant类类似于最常见的Qt数据类型的联合。由于C禁止联合类型包括具有非默认构造函数或析构函数的类型&#xff0c;大多数有趣的Qt类不能在联合中使用。如果没有QVariant&#xff0c;则QObject::property()和数据库操作等将会受到影响。 QVariant对象同时持有一个单一…...

xv6实验课程--xv6的写时复制fork(2023)

7. xv6实验课程--xv6的写时拷贝(COW)(2021) 7. xv6实验课程--xv6懒惰分页分配&#xff08;lazy)(2020) 本文来源&#xff1a; https://mp.weixin.qq.com/s/XJkhjrlP232ZDsRyXd0oHQ 已完成的实验代码可以从下列网站获取&#xff1a; git clone https://gitee.com/lhwhit196…...

在Windows或Mac上安装并运行LLAMA2

LLAMA2在不同系统上运行的结果 LLAMA2 在windows 上运行的结果 LLAMA2 在Mac上运行的结果 安装Llama2的不同方法 方法一&#xff1a; 编译 llama.cpp 克隆 llama.cpp git clone https://github.com/ggerganov/llama.cpp.git 通过conda 创建或者venv. 下面是通过conda 创建…...

Spring底层原理学习笔记--第七讲--(初始化与销毁)

初始化与销毁 Spring提供了多种初始化和销毁手段它们的执行顺序 A07Application.java package com.lucifer.itheima.a07;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springfram…...

基于斑马算法的无人机航迹规划-附代码

基于斑马算法的无人机航迹规划 文章目录 基于斑马算法的无人机航迹规划1.斑马搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用斑马算法来优化无人机航迹规划。 1.斑马搜索算法 …...

干货 | 接口自动化测试分层设计与实践总结

接口测试三要素&#xff1a; 参数构造 发起请求&#xff0c;获取响应 校验结果 一、原始状态 当我们的用例没有进行分层设计的时候&#xff0c;只能算是一个“苗条式”的脚本。以一个后台创建商品活动的场景为例&#xff0c;大概流程是这样的(默认已经是登录状态下)&#…...

【Linux】服务器与磁盘补充知识,硬raid操作指南

服务器硬件 cpu 主板 内存 硬盘 网卡 电源 raid卡 风扇 远程管理卡 1.硬盘尺寸: 目前生产环境中主流的两种类型硬盘 3.5寸 和2.5寸硬盘 2.5寸硬盘可以通过使用硬盘托架后适用于3.5寸硬盘的服务器 但是3.5寸没法转换成2.5寸 2.如何在服务器上制作raid 华为服务器为例子做…...

【java】实现自定义注解校验——方法二

自定义注解校验的实现步骤&#xff1a; 1.创建注解类&#xff0c;编写校验注解&#xff0c;即类似NotEmpty注解 2.编写自定义校验的逻辑实体类&#xff0c;编写具体的校验逻辑。(这个类可以实现ConstraintValidator这个接口&#xff0c;让注解用来校验) 3.开启使用自定义注解进…...