返回顶部
首页 > 资讯 > 精选 >Java Log框架源码分析
  • 889
分享到

Java Log框架源码分析

2023-07-05 13:07:00 889人浏览 安东尼
摘要

这篇文章主要讲解了“Java Log框架源码分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java Log框架源码分析”吧!Log4J、Log4J2和LogBack的

这篇文章主要讲解了“Java Log框架源码分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java Log框架源码分析”吧!

Log4J、Log4J2和LogBack的历史故事

使用过Log4J和LogBack的同学肯定能发现,这两个框架的设计理念极为相似,使用方法也如出一辙。其实这个两个框架的作者都是一个人,Ceki Gülcü,俄罗斯程序员

Log4J 最初是基于Java开发日志框架,发展一段时间后,作者Ceki Gülcü将Log4j捐献给了Apache软件基金会,使之成为了Apache日志服务的一个子项目。 又由于Log4J出色的表现,后续又被孵化出了支持C, c++, C#, Perl, python, Ruby等语言的子框架。

然而,伟大的程序员好像都比较有个性。Ceki Gülcü由于不满Apache对Log4J的管理,决定不再参加Log4J的开发维护。“出走”后的Ceki Gülcü另起炉灶,开发出了LogBack这个框架(SLF4J是和LogBack一起开发出来的)。LogBack改进了很多Log4J的缺点,在性能上有了很大的提升,同时使用方式几乎和Log4J一样,许多用户开始慢慢开始使用LogBack。

由于受到LogBack的冲击,Log4J开始式微。终于,2015年9月,Apache软件基金业宣布,Log4j不在维护,建议所有相关项目升级到Log4j2。Log4J2是Apache开发的一个新的日志框架,改进了很多Log4J的缺点,同时也借鉴了LogBack,号称在性能上也是完胜LogBack。性能这块后面我会仔细分析。

那slf4j和这些有什么关系?

SLF4J的全称是Simple Logging Facade for Java,slf4j是门面模式的典型应用,因此在讲slf4j前,需要简单介绍下门面模式。

看看门面模式再说

下面是门面模式的一个典型调用过程,其核心为外部与一个子系统的通信必须通过一个统一的外观对象进行,使得子系统更易于使用。 下图中客户端不需要直接调用几个子系统,只需要与统一的门面进行通信即可。

Java Log框架源码分析

门面模式的核心为Facade即门面对象,核心为几个点:

  • 知道所有子角色的功能和责任。

  • 将客户端发来的请求委派到子系统中,没有实际业务逻辑。

  • 不参与子系统内业务逻辑的实现。

为什么要使用slf4j ?

回答这个问题之前,我们先看看如果需要用上面几个日志框架来打印日志,一般怎么做,具体代码如下:

// 使用log4j,需要log4j.jarimport org.apache.log4j.Logger;Logger logger_log4j = Logger.getLogger(Test.class);logger_log4j.info("Hello World!");// 使用log4j2,需要log4j-api.jar、log4j-core.jarimport org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;Logger logger_log4j2 = LogManager.getLogger(Test.class);logger_log4j2.info("Hello World!");// logback,需要logback-classic.jar、logback-core.jarimport ch.qos.logback.classic.Logger;import ch.qos.logback.classic.LoggerContext;Logger logger_logback = new LoggerContext().getLogger(Test.class);logger_logback.info("Hello World!");

从上面不难看出,使用不同的日志框架,就要引入不同的jar包,使用不同的代码获取Logger。如果项目升级需要更换不同的框架,那么就需要修改所有的地方来获取新的Logger,这将会产生巨大的工作量。

基于此,我们需要一种接口来将不同的日志框架的使用统一起来,这也是为什么要使用slf4j的原因。

SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统。按照官方的说法,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志系统。

注意:类似的日志门面还有Jakarta Common logging(JCL),主要区别在于,SLF4J是一个比较新的日志框架,它更加灵活,性能更好,支持更多的日志实现,而且JCL基于classLoader在运行时动态加载日志框架,可能会产生很多意想不到的安全问题。

通过上面的介绍,我们可以知道JCL和SLF4J都是日志门面(Facade),而Log4J、Log4J2和LogBack都是子系统角色(SunSystem),也就是具体的日志实现框架。他们的关系如下,JUL是jdk本身提供的一种实现。

Java Log框架源码分析

使用日志门面引入日志组件的最大优势是:将系统和具体的日志实现框架解耦合。

slf4j怎么和日志框架结合使用?

使用slf4j后,当我们在打印日志时,就可以使用下面的方式:

import org.slf4j.Logger;import org.slf4j.LoggerFactory;Logger logger = LoggerFactory.getLogger(Test.class);logger.info("Hello World!")

这又引入了另外一个问题,slf4j如何决定使用哪个框架日志呢,并且引入哪些jar包呢?官方为我们准备了下面的组合依赖结构图:

Java Log框架源码分析

总结来说,就是一下几种:

  • slf4j + logback: slf4j-api.jar + logback-classic.jar + logback-core.jar

  • slf4j + log4j: slf4j-api.jar + slf4j-log412.jar + log4j.jar

  • slf4j + jul: slf4j-api.jar + slf4j-jdk14.jar

  • 也可以只用slf4j无日志实现:slf4j-api.jar + slf4j-nop.jar

注意到这里没有log4j2依赖jar的关系,和log4j2配合需要导入log4j2的log4j-api.jar、log4j-core.jar和桥接包log4j-slf4j-impl.jar。

所谓的桥接包,就是实现StaticLoggerBinder类,用来连接slf4j和日志框架。因为log4j和log4j2刚开始没有StaticLoggerBinder这个类,为了不改变程序结构,只能重新写一个新的jar来实现StaticLoggerBinder。而logback出现slf4j之后,于是在logback本身的jar中实现了StaticLoggerBinder,所以就不需要桥接包。

现在为什么推荐Log4j2?

Apache Log4j 2 是 Log4j(1) 的升级版,比它的祖先 Log4j 1.x和logback 有了很大的改进。除了内部设计的调整外,主要有以下几点的大升级:

  • 更简化的配置

  • 更强大的参数格式化

  • 最夸张的异步性能

Log4j2 中,分为 API(log4j-api)和实现 (log4j-core) 两个模块。API 和 slf4j 是一个类型,属于日志抽象 / 门面,而实现部分,才是 Log4j 2 的核心。

  • org.apache.logging.log4j » log4j-api

  • org.apache.logging.log4j » log4j-core

log4j2 在目前 JAVA 中的日志框架里,异步日志的性能是最高的,具体可以看下面的对比图:

Java Log框架源码分析

log4j2采用了字符串复用等手段来实现零GC模式运行,另外提供了MemoryMappedFileAppender实现了极高的io性能,而且API相比slf4j,有更丰富的参数格式化功能。

怎么使用Log4j2?

说了半天,那怎么去使用Log4j2呢,这部分我仔细介绍一下。

常规使用步骤

下面以Maven配置为例进行介绍。

首先需要加入log4j的依赖,注意2.17.1以下的版本会有远程代码执行的安全漏洞,具体参考Apache官方文档(https://logging.apache.org/log4j/2.x/security.html)。推荐使用最新的版本。

<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.17.2</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.17.2</version></dependency>

配置好log4j2.xml配置文件,并放到项目的classpath里面,一般会放到resources目录里面。下面是一个参考的配置,当然也可以使用properties文件和yaml文件来进行配置。

<?xml version="1.0" encoding="UTF-8"?><Configuration status="WARN">    <Appenders>        <Console name="LogToConsole" target="SYSTEM_OUT">            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>        </Console>    </Appenders>    <Loggers>        <Logger name="com.malaoshi" level="debug" additivity="false">            <AppenderRef ref="LogToConsole"/>        </Logger>        <Root level="error">            <AppenderRef ref="LogToConsole"/>        </Root>    </Loggers></Configuration>

在程序中打印log。使用下面的方式来打印log即可。

import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;public class HelloWorld {    private static final Logger logger = LogManager.getLogger(HelloWorld.class);    public static void main(String[] args) {        logger.debug("Hello from Log4j 2");        // in old days, we need to check the log level to increase perfORMance                // with Java 8, we can do this, no need to check the log level        logger.debug("{}", () -> getNumber());    }    static int getNumber() {        return 5;    }}

输出如下:

12:25.337 [main] DEBUG com.malaoshi.HelloWorld - Hello from Log4j 2
19:12:25.340 [main] DEBUG com.malaoshi.HelloWorld - 5

配置文件详解

首先给大家看一个比较全面的配置文件,可能看起来比较头大,不急我后面会一点点仔细分析。

<?xml version="1.0" encoding="UTF-8"?> <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> <!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出--> <!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数--> <configuration status="WARN" monitorInterval="30">     <!--先定义所有的appender-->     <appenders>     <!--这个输出控制台的配置-->         <console name="Console" target="SYSTEM_OUT">         <!--输出日志的格式-->             <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>         </console>     <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->     <File name="log" fileName="log/test.log" append="false">        <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>     </File>     <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->         <RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log"                      filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">             <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->                     <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>             <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>             <Policies>                 <TimeBasedTriggeringPolicy/>                 <SizeBasedTriggeringPolicy size="100 MB"/>             </Policies>         </RollingFile>         <RollingFile name="RollingFileWarn" fileName="${sys:user.home}/logs/warn.log"                      filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">             <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>             <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>             <Policies>                 <TimeBasedTriggeringPolicy/>                 <SizeBasedTriggeringPolicy size="100 MB"/>             </Policies>         <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->             <DefaultRolloverStrategy max="20"/>         </RollingFile>         <RollingFile name="RollingFileError" fileName="${sys:user.home}/logs/error.log"                      filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">             <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>             <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>             <Policies>                 <TimeBasedTriggeringPolicy/>                 <SizeBasedTriggeringPolicy size="100 MB"/>             </Policies>         </RollingFile>     </appenders>     <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->     <loggers>         <!--过滤掉springmybatis的一些无用的DEBUG信息-->         <logger name="org.springframework" level="INFO"></logger>         <logger name="org.mybatis" level="INFO"></logger>         <root level="all">             <appender-ref ref="Console"/>             <appender-ref ref="RollingFileInfo"/>             <appender-ref ref="RollingFileWarn"/>             <appender-ref ref="RollingFileError"/>         </root>     </loggers> </configuration>

下面为大家仔细解析这个配置文件,

根节点

Configuration有两个属性:status和monitorinterval,有两个子节点:Appenders和Loggers(表明可以定义多个Appender和Logger)。

  • status用来指定log4j本身的打印日志的级别.

  • monitorinterval用于指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s.

Appenders节点

Appenders节点,常见的子节点有:Console、RollingFile、File。

Console节点用来定义输出到控制台的Appender。

  • name:指定Appender的名字。

  • target:SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认:SYSTEM_OUT。

  • PatternLayout:输出格式,不设置默认为:%m%n。

File节点用来定义输出到指定位置的文件的Appender。

  • name:指定Appender的名字。

  • fileName:指定输出日志的目的文件带全路径的文件名。

  • PatternLayout:输出格式,不设置默认为:%m%n。

RollingFile节点用来定义超过指定大小自动删除旧的创建新的的Appender。

  • name:指定Appender的名字。

  • fileName:指定输出日志的目的文件带全路径的文件名。

  • PatternLayout:输出格式,不设置默认为:%m%n。

  • filePattern:指定新建日志文件的名称格式。

  • Policies是指定滚动日志的策略,就是什么时候进行新建日志文件输出日志。

TimeBasedTriggeringPolicy:Policies子节点,基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour。modulate=true用来调整时间:比如现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am。
SizeBasedTriggeringPolicy:Policies子节点,基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小。

DefaultRolloverStrategy:用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的,创建新的(通过max属性)。

Loggers

Loggers节点,常见子节点有:Root和Logger。

Root节点用来指定项目的根日志,如果没有单独指定Logger,那么就会默认使用该Root日志输出

  • level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF。

  • AppenderRef:Root的子节点,用来指定该日志输出到哪个Appender。

Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。

  • level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF。

  • name:用来指定该Logger所适用的类或者类所在的包全路径,继承自Root节点。

  • AppenderRef:Logger的子节点,用来指定该日志输出到哪个Appender,如果没有指定,就会默认继承自Root.如果指定了,那么会在指定的这个Appender和Root的Appender中都会输出,此时我们可以设置Logger的additivity="false"只在自定义的Appender中进行输出。

日志Level

共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF。

  • All:最低等级的,用于打开所有日志记录。

  • Trace:是追踪,就是程序推进以下,你就可以写个trace输出,所以trace应该会特别多,不过没关系,我们可以设置最低日志级别不让他输出。

  • Debug:指出细粒度信息事件对调试应用程序是非常有帮助的。

  • Info:消息在粗粒度级别上突出强调应用程序的运行过程。

  • Warn:输出警告及warn以下级别的日志。

  • Error:输出错误信息日志。

  • Fatal:输出每个严重的错误事件将会导致应用程序的退出的日志。

  • OFF:最高等级的,用于关闭所有日志记录。

程序会打印高于或等于所设置级别的日志,设置的日志等级越高,打印出来的日志就越少。

参考范例

这部分给大家提供几个常用的配置,直接放到项目里面改一下包名就可以用。

输出日志到Console

<?xml version="1.0" encoding="UTF-8"?><Configuration status="DEBUG">    <Appenders>        <Console name="LogToConsole" target="SYSTEM_OUT">            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>        </Console>    </Appenders>    <Loggers><!-- avoid duplicated logs with additivity=false -->        <Logger name="com.mkyong" level="debug" additivity="false">            <AppenderRef ref="LogToConsole"/>        </Logger>        <Root level="error">            <AppenderRef ref="LogToConsole"/>        </Root>    </Loggers></Configuration>

输出日志到文件

<?xml version="1.0" encoding="UTF-8"?><Configuration status="DEBUG">    <Appenders>        <Console name="LogToConsole" target="SYSTEM_OUT">            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>        </Console>        <File name="LogToFile" fileName="logs/app.log">            <PatternLayout>                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>            </PatternLayout>        </File>    </Appenders>    <Loggers>        <Logger name="com.malaoshi" level="debug" additivity="false">            <AppenderRef ref="LogToFile"/>            <AppenderRef ref="LogToConsole"/>        </Logger>        <Logger name="org.springframework.boot" level="error" additivity="false">            <AppenderRef ref="LogToConsole"/>        </Logger>        <Root level="error">            <AppenderRef ref="LogToFile"/>            <AppenderRef ref="LogToConsole"/>        </Root>    </Loggers></Configuration>

输出到文件并滚动生成新的日志文件

<Configuration status="DEBUG">    <Appenders>        <Console name="LogToConsole" target="SYSTEM_OUT">            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>        </Console>        <RollingFile name="LogToRollingFile" fileName="logs/app.log"                    filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"><PatternLayout><Pattern>%d %p %c{1.} [%t] %m%n</Pattern></PatternLayout><Policies><TimeBasedTriggeringPolicy /><SizeBasedTriggeringPolicy size="10 MB"/></Policies></RollingFile>    </Appenders>    <Loggers>        <!-- avoid duplicated logs with additivity=false -->        <Logger name="com.malaoshi" level="debug" additivity="false">            <AppenderRef ref="LogToRollingFile"/>        </Logger>        <Root level="error">            <AppenderRef ref="LogToConsole"/>        </Root>    </Loggers></Configuration>

感谢各位的阅读,以上就是“Java Log框架源码分析”的内容了,经过本文的学习后,相信大家对Java Log框架源码分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: Java Log框架源码分析

本文链接: https://lsjlt.com/news/352063.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java Log框架源码分析
    这篇文章主要讲解了“Java Log框架源码分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java Log框架源码分析”吧!Log4J、Log4J2和LogBack的...
    99+
    2023-07-05
  • Mybatis Plus框架源码分析
    这篇文章主要介绍了Mybatis Plus框架源码分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Mybatis Plus框架源码分析文章都会有所收获,下面我们一起来看看吧。基础设计Bas...
    99+
    2023-07-05
  • Java集合框架概览之ArrayList源码分析
    今天小编给大家分享一下Java集合框架概览之ArrayList源码分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、从一...
    99+
    2023-07-05
  • 微前端框架qiankun源码分析
    本文小编为大家详细介绍“微前端框架qiankun源码分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“微前端框架qiankun源码分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、single-spa简介要...
    99+
    2023-07-05
  • Java OkHttp框架源码超详细解析
    目录一、自己的理解的OkHttp二、OkHttp的使用方法三、基本对象介绍1.OkHttpClient2.request3.Call4.RealCall5.AsyncCall6.Di...
    99+
    2022-11-13
    Java OkHttp框架 OkHttp源码 OkHttp框架
  • Java WebService开源框架CXF案例分析
    本篇内容介绍了“Java WebService开源框架CXF案例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!CXF简介CXF...
    99+
    2023-06-25
  • Android动画(四)动画框架源码分析
    本篇难度较大,慎入 也许可以先去看总结在来一起分析 从我们写的开始进入: fun click(view: View) { va...
    99+
    2022-06-06
    源码 框架 Android
  • Android框架之OkHttp3源码的示例分析
    这篇文章将为大家详细讲解有关Android框架之OkHttp3源码的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。OkHttp流程图OkHttp基本使用gradle依赖implementation...
    99+
    2023-06-15
  • Android框架之Volley源码的示例分析
    这篇文章主要介绍Android框架之Volley源码的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Volley简单使用我这里是以依赖架包的形式 ,大家也可以以gradle的形式进行依赖。好了,接下来上代码了...
    99+
    2023-06-15
  • 怎么解析jQuery框架源码
    怎么解析jQuery框架源码,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。对于jQuery只停留在应用是可悲的,在做项目的过程,jquer...
    99+
    2024-04-02
  • 解析Android框架之Volley源码
    目录Volley简单使用Volley执行原理Volley简单使用 我这里是以依赖架包的形式 ,大家也可以以gradle的形式进行依赖。 好了,接下来上代码了..... //获取...
    99+
    2024-04-02
  • 解析Android框架之OkHttp3源码
    目录OkHttp流程图OkHttp基本使用OkHttp源码分析OkHttp流程图 OkHttp基本使用 gradle依赖 implementation 'com.squareup...
    99+
    2024-04-02
  • JavaOkHttp框架源码深入解析
    目录1.OkHttp发起网络请求可以通过OkHttpClient发起一个网络请求通过Retrofit发起一个OkHttp请求2.OkHttp的连接器1.OkHttp发起网络请求 可以...
    99+
    2024-04-02
  • 如何进行jQuery源码的整体框架分析
    这篇文章将为大家详细讲解有关如何进行jQuery源码的整体框架分析,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。先附上jQuery的代码结构。JS代码(fu...
    99+
    2024-04-02
  • python架构PyNeuraLogic源码分析
    这篇“python架构PyNeuraLogic源码分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“python架构PyNe...
    99+
    2023-07-05
  • Java ConcurrentHashMap源码分析
    这篇“Java ConcurrentHashMap源码分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java&...
    99+
    2023-07-05
  • 【Django】REST_Framework框架——APIView类源码解析
    一、APIView类源码解析 1、APIView是REST framework提供的所有视图的基类,继承自Django的View父类。 2、APIView与 View的不同之处在于: 1、传入到...
    99+
    2023-09-14
    django python 后端
  • Android Volley框架使用源码分享
    过去在Android上网络通信都是使用的Xutils 因为用它可以顺道处理了图片和网络这两个方面,后来发觉Xutils里面使用的是HttpClient  而Googl...
    99+
    2022-06-06
    volley框架 volley 源码分享 源码 Android
  • 简略分析Android的Retrofit应用开发框架源码
    面对一个项目,对于Android应用开发框架的选择,我想过三种方案: 1.使用Loader + HttpClient + GreenDao + Gson + Fragment,...
    99+
    2022-06-06
    retrofit 开发框架 源码 框架 Android
  • ZooKeeper框架教程Curator分布式锁实现及源码分析
    目录  如何使用InterProcessMutex  实现思路   代码实现概述  InterProcessMutex源码分析&nb...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作