jcl與jul?log4j1?log4j2?logback日志系統(tǒng)機(jī)制及集成原理
系列文章已完成,目錄如下:
jdk-logging log4j logback日志系統(tǒng)實(shí)現(xiàn)機(jī)制原理介紹
slf4j與jul、log4j1、log4j2、logback的集成原理
slf4j、jcl、jul、log4j1、log4j2、logback大總結(jié)
前面介紹了jdk自帶的logging、log4j1、log4j2、logback等實(shí)際的日志框架
對(duì)于開(kāi)發(fā)者而言,每種日志都有不同的寫(xiě)法。如果我們以實(shí)際的日志框架來(lái)進(jìn)行編寫(xiě),代碼就限制死了,之后就很難再更換日志系統(tǒng),很難做到無(wú)縫切換。
java web開(kāi)發(fā)就經(jīng)常提到一項(xiàng)原則:面向接口編程,而不是面向?qū)崿F(xiàn)編程
所以我們應(yīng)該是按照一套統(tǒng)一的API來(lái)進(jìn)行日志編程,實(shí)際的日志框架來(lái)實(shí)現(xiàn)這套API,這樣的話,即使更換日志框架,也可以做到無(wú)縫切換。
這就是commons-logging與slf4j的初衷。
下面就來(lái)介紹下commons-logging與slf4j這兩個(gè)門(mén)面如何與上述四個(gè)實(shí)際的日志框架進(jìn)行集成的呢
介紹之前先說(shuō)明下日志簡(jiǎn)稱(chēng):
jdk自帶的logging->簡(jiǎn)稱(chēng) jul (java-util-logging)
apache commons-logging->簡(jiǎn)稱(chēng) jcl
apache commons-logging
先從一個(gè)簡(jiǎn)單的使用案例來(lái)說(shuō)明
1 簡(jiǎn)單的使用案例
private static Log logger=LogFactory.getLog(JulJclTest.class); public static void main(String[] args){ if(logger.isTraceEnabled()){ logger.trace("commons-logging-jcl trace message"); } if(logger.isDebugEnabled()){ logger.debug("commons-logging-jcl debug message"); } if(logger.isInfoEnabled()){ logger.info("commons-logging-jcl info message"); } }
上述Log、LogFactory都是commons-logging自己的接口和類(lèi)
2 使用原理
LogFactory.getLog(JulJclTest.class)的源碼如下:
public static Log getLog(Class clazz) throws LogConfigurationException { return getFactory().getInstance(clazz); }
上述獲取Log的過(guò)程大致分成2個(gè)階段
- 獲取LogFactory的過(guò)程 (從字面上理解就是生產(chǎn)Log的工廠)
- 根據(jù)LogFactory獲取Log的過(guò)程
commons-logging默認(rèn)提供的LogFactory實(shí)現(xiàn):LogFactoryImpl commons-logging默認(rèn)提供的Log實(shí)現(xiàn):Jdk14Logger、Log4JLogger、SimpleLog。
來(lái)看下commons-logging包中的大概內(nèi)容:
下面來(lái)詳細(xì)說(shuō)明:
1 獲取LogFactory的過(guò)程
從下面幾種途徑來(lái)獲取LogFactory
1.1 系統(tǒng)屬性中獲取,即如下形式
System.getProperty("org.apache.commons.logging.LogFactory")
1.2 使用java的SPI機(jī)制,來(lái)搜尋對(duì)應(yīng)的實(shí)現(xiàn)
對(duì)于java的SPI機(jī)制,詳細(xì)內(nèi)容可以自行搜索,這里不再說(shuō)明。搜尋路徑如下:
META-INF/services/org.apache.commons.logging.LogFactory
簡(jiǎn)單來(lái)說(shuō)就是搜尋哪些jar包中含有搜尋含有上述文件,該文件中指明了對(duì)應(yīng)的LogFactory實(shí)現(xiàn)
1.3 從commons-logging的配置文件中尋找
commons-logging也是可以擁有自己的配置文件的,名字為commons-logging.properties,只不過(guò)目前大多數(shù)情況下,我們都沒(méi)有去使用它。如果使用了該配置文件,嘗試從配置文件中讀取屬性"org.apache.commons.logging.LogFactory"對(duì)應(yīng)的值
1.4 最后還沒(méi)找到的話,使用默認(rèn)的org.apache.commons.logging.impl.LogFactoryImpl
LogFactoryImpl是commons-logging提供的默認(rèn)實(shí)現(xiàn)
2 根據(jù)LogFactory獲取Log的過(guò)程
這時(shí)候就需要尋找底層是選用哪種類(lèi)型的日志
就以commons-logging提供的默認(rèn)實(shí)現(xiàn)為例,來(lái)詳細(xì)看下這個(gè)過(guò)程:
2.1 從commons-logging的配置文件中尋找Log實(shí)現(xiàn)類(lèi)的類(lèi)名
從commons-logging.properties配置文件中尋找屬性為"org.apache.commons.logging.Log"對(duì)應(yīng)的Log類(lèi)名
2.2 從系統(tǒng)屬性中尋找Log實(shí)現(xiàn)類(lèi)的類(lèi)名
即如下方式獲取:
System.getProperty("org.apache.commons.logging.Log")
2.3 如果上述方式?jīng)]找到,則從classesToDiscover屬性中尋找
classesToDiscover屬性值如下:
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" };
它會(huì)嘗試根據(jù)上述類(lèi)名,依次進(jìn)行創(chuàng)建,如果能創(chuàng)建成功,則使用該Log,然后返回給用戶(hù)。
下面針對(duì)具體的日志框架,看看commons-logging是如何集成的
commons-logging與jul集成
1 需要的jar包
commons-logging
對(duì)應(yīng)的maven依賴(lài)是:
<dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency>
2 使用案例
private static Log logger=LogFactory.getLog(JulJclTest.class); public static void main(String[] args){ if(logger.isTraceEnabled()){ logger.trace("commons-logging-jcl trace message"); } if(logger.isDebugEnabled()){ logger.debug("commons-logging-jcl debug message"); } if(logger.isInfoEnabled()){ logger.info("commons-logging-jcl info message"); } }
結(jié)果輸出如下:
四月 27, 2015 11:13:33 下午 com.demo.log4j.JulJclTest main
信息: commons-logging-jcl info message
3 使用案例分析
案例過(guò)程分析,就是看看上述commons-logging的在執(zhí)行原理的過(guò)程中是如何來(lái)走的
1 獲取獲取LogFactory的過(guò)程
所以commons-logging會(huì)使用默認(rèn)的LogFactoryImpl作為L(zhǎng)ogFactory
- 1.1 我們沒(méi)有配置系統(tǒng)屬性"org.apache.commons.logging.LogFactory"
- 1.2 我們沒(méi)有配置commons-logging的commons-logging.properties配置文件
- 1.3 也沒(méi)有含有"META-INF/services/org.apache.commons.logging.LogFactory"路徑的jar包
2 根據(jù)LogFactory獲取Log的過(guò)程
所以就需要依次根據(jù)classesToDiscover中的類(lèi)名稱(chēng)進(jìn)行創(chuàng)建。
2.1 我們沒(méi)有配置commons-logging的commons-logging.properties配置文件
2.2 我們沒(méi)有配置系統(tǒng)屬性"org.apache.commons.logging.Log"
2.3 先是創(chuàng)建org.apache.commons.logging.impl.Log4JLogger
創(chuàng)建失敗,因?yàn)樵擃?lèi)是依賴(lài)org.apache.log4j包中的類(lèi)的
2.4 接著創(chuàng)建org.apache.commons.logging.impl.Jdk14Logger
創(chuàng)建成功,所以我們返回的就是Jdk14Logger,看下它是如何與jul集成的
它內(nèi)部有一個(gè)java.util.logging.Logger logger屬性,所以Jdk14Logger的info("commons-logging-jcl info message")操作都會(huì)轉(zhuǎn)化成由java.util.logging.Logger來(lái)實(shí)現(xiàn):
上述logger的來(lái)歷:
logger = java.util.logging.Logger.getLogger(name);
就是使用jul原生的方式創(chuàng)建的一個(gè)java.util.logging.Logger,參見(jiàn)jdk-logging的原生寫(xiě)法
是如何打印info信息的呢?
使用jul原生的方式:
logger.log(Level.WARNING,"commons-logging-jcl info message");
由于jul默認(rèn)的級(jí)別是INFO級(jí)別(見(jiàn)上一篇文章的說(shuō)明中的配置文件jdk自帶的logging),所以只打出了如下信息:
四月 27, 2015 11:41:24 下午 com.demo.log4j.JulJclTest main
信息: commons-logging-jcl info message
原生的jdk的logging的日志級(jí)別是FINEST、FINE、INFO、WARNING、SEVERE分別對(duì)應(yīng)我們常見(jiàn)的trace、debug、info、warn、error。
commons-logging與log4j1集成
1 需要的jar包
commons-logging
log4j
對(duì)應(yīng)的maven依賴(lài)是:
<dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
4.2 使用案例
在類(lèi)路徑下加入log4j的配置文件log4j.properties
log4j.rootLogger = trace, console log4j.appender.console = org.apache.log4j.ConsoleAppender log4j.appender.console.layout = org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} %m%n
使用方式如下:
private static Log logger=LogFactory.getLog(Log4jJclTest.class); public static void main(String[] args){ if(logger.isTraceEnabled()){ logger.trace("commons-logging-log4j trace message"); } if(logger.isDebugEnabled()){ logger.debug("commons-logging-log4j debug message"); } if(logger.isInfoEnabled()){ logger.info("commons-logging-log4j info message"); } }
代碼沒(méi)變,還是使用commons-logging的接口和類(lèi)來(lái)編程,沒(méi)有l(wèi)og4j的任何影子。這樣,commons-logging就與log4j集成了起來(lái),我們可以通過(guò)log4j的配置文件來(lái)控制日志的顯示級(jí)別
上述是trace級(jí)別(小于debug),所以trace、debug、info的都會(huì)顯示出來(lái)
3 使用案例分析
案例過(guò)程分析,就是看看上述commons-logging的在執(zhí)行原理的過(guò)程中是如何來(lái)走的:
1 獲取獲取LogFactory的過(guò)程
同上述jcl的過(guò)程一樣,使用默認(rèn)的LogFactoryImpl作為L(zhǎng)ogFactory
2 根據(jù)LogFactory獲取Log的過(guò)程
同上述jcl的過(guò)程一樣,最終會(huì)依次根據(jù)classesToDiscover中的類(lèi)名稱(chēng)進(jìn)行創(chuàng)建:
先是創(chuàng)建org.apache.commons.logging.impl.Log4JLogger
創(chuàng)建成功,因?yàn)榇藭r(shí)含有l(wèi)og4j的jar包,所以返回的是Log4JLogger,我們看下它與commons-logging是如何集成的:
它內(nèi)部有一個(gè)org.apache.log4j.Logger logger屬性,這個(gè)是log4j的原生Logger。所以Log4JLogger都是委托這個(gè)logger來(lái)完成的
2.1 org.apache.log4j.Logger logger來(lái)歷
org.apache.log4j.Logger.getLogger(name)
使用原生的log4j1的寫(xiě)法來(lái)生成,參見(jiàn)之前l(fā)og4j原生的寫(xiě)法log4j1原生的寫(xiě)法,我們知道上述過(guò)程會(huì)引發(fā)log4j1的配置文件的加載,之后就進(jìn)入log4j1的世界了
2.2 輸出日志
測(cè)試案例中我們使用commons-logging輸出的日志的形式如下(這里的logger是org.apache.commons.logging.impl.Log4JLogger類(lèi)型):
logger.debug("commons-logging-log4j debug message");
其實(shí)就會(huì)轉(zhuǎn)換成log4j原生的org.apache.log4j.Logger對(duì)象(就是上述獲取的org.apache.log4j.Logger類(lèi)型的logger對(duì)象)的如下輸出:
logger.debug("log4j debug message");
上述過(guò)程最好與log4j1的原生方式對(duì)比著看,見(jiàn)log4j1的原生方式
commons-logging與log4j2集成
1 需要的jar包
commons-logging
log4j-api (log4j2的API包)
log4j-core (log4j2的API實(shí)現(xiàn)包)
log4j-jcl (log4j2與commons-logging的集成包)
對(duì)應(yīng)的maven依賴(lài)是:
<dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-jcl</artifactId> <version>2.2</version> </dependency>
2 使用案例
編寫(xiě)log4j2的配置文件log4j2.xml,簡(jiǎn)單如下:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="debug"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>
使用案例如下:
private static Log logger=LogFactory.getLog(Log4j2JclTest.class); public static void main(String[] args){ if(logger.isTraceEnabled()){ logger.trace("commons-logging-log4j trace message"); } if(logger.isDebugEnabled()){ logger.debug("commons-logging-log4j debug message"); } if(logger.isInfoEnabled()){ logger.info("commons-logging-log4j info message"); } }
仍然是使用commons-logging的Log接口和LogFactory來(lái)進(jìn)行編寫(xiě),看不到log4j2的影子。但是這時(shí)候含有上述幾個(gè)jar包,log4j2就與commons-logging集成了起來(lái)。
3 使用案例分析
案例過(guò)程分析,就是看看上述commons-logging的在執(zhí)行原理的過(guò)程中是如何來(lái)走的:
1 先來(lái)看下上述 log4j-jcl(log4j2與commons-logging的集成包)的來(lái)歷:
我們知道,commons-logging原始的jar包中使用了默認(rèn)的LogFactoryImpl作為L(zhǎng)ogFactory,該默認(rèn)的LogFactoryImpl中的classesToDiscover(到上面查看它的內(nèi)容)并沒(méi)有l(wèi)og4j2對(duì)應(yīng)的Log實(shí)現(xiàn)類(lèi)。所以我們就不能使用這個(gè)原始包中默認(rèn)的LogFactoryImpl了,需要重新指定一個(gè),并且需要給出一個(gè)apache的Log實(shí)現(xiàn)(該Log實(shí)現(xiàn)是用于log4j2的),所以就產(chǎn)生了log4j-jcl這個(gè)jar包,來(lái)看下這個(gè)jar包的大致內(nèi)容:
這里面的LogFactoryImpl就是要準(zhǔn)備替換commons-logging中默認(rèn)的LogFactoryImpl(其中META-INF/services/下的那個(gè)文件起到重要的替換作用,下面詳細(xì)說(shuō))
這里面的Log4jLog便是針對(duì)log4j2的,而commons-logging中的原始的Log4JLogger則是針對(duì)log4j1的。它們都是commons-logging的Log接口的實(shí)現(xiàn)
2 獲取獲取LogFactory的過(guò)程
這個(gè)過(guò)程就和jul、log4j1的集成過(guò)程不太一樣了。通過(guò)java的SPI機(jī)制,找到了org.apache.commons.logging.LogFactory對(duì)應(yīng)的實(shí)現(xiàn),即在log4j-jcl包中找到的,其中META-INF/services/org.apache.commons.logging.LogFactory中的內(nèi)容是:
org.apache.logging.log4j.jcl.LogFactoryImpl
即指明了使用log4j-jcl中的LogFactoryImpl作為L(zhǎng)ogFactory
3 根據(jù)LogFactory獲取Log的過(guò)程
就來(lái)看下log4j-jcl中的LogFactoryImpl是怎么實(shí)現(xiàn)的
public class LogFactoryImpl extends LogFactory { private final LoggerAdapter<Log> adapter = new LogAdapter(); //略 }
這個(gè)LoggerAdapter是lo4j2中的一個(gè)適配器接口類(lèi),根據(jù)log4j2生產(chǎn)的原生的org.apache.logging.log4j.Logger實(shí)例,將它包裝成你指定的泛型類(lèi)。
這里使用的LoggerAdapter實(shí)現(xiàn)是LogAdapter,它的內(nèi)容如下:
public class LogAdapter extends AbstractLoggerAdapter<Log> { @Override protected Log newLogger(final String name, final LoggerContext context) { return new Log4jLog(context.getLogger(name)); } @Override protected LoggerContext getContext() { return getContext(ReflectionUtil.getCallerClass(LogFactory.class)); } }
我們可以看到,它其實(shí)就是將原生的log4j2的Logger封裝成Log4jLog。這里就可以看明白了,下面來(lái)詳細(xì)的走下流程,看看是什么時(shí)候來(lái)初始化log4j2的:
至此,我們通過(guò)Log4jLog實(shí)例打印的日志都是委托給了它內(nèi)部包含的log4j2的原生Logger對(duì)象了。
3.1 首先獲取log4j2中的重要配置對(duì)象LoggerContext,LogAdapter的實(shí)現(xiàn)如上面的源碼(使用父類(lèi)的getContext方法),父類(lèi)方法的內(nèi)容如下:
LogManager.getContext(cl, false);
我們可以看到這其實(shí)就是使用log4j2的LogManager進(jìn)行初始化的,至此就進(jìn)入log4j2的初始化的世界了。
3.2 log4j2的LoggerContext初始化完成后,該生產(chǎn)一個(gè)log4j2原生的Logger對(duì)象
使用log4j2原生的方式:
context.getLogger(name)
3.3 將上述方式產(chǎn)生的Log4j原生的Logger實(shí)例進(jìn)行包裝,包裝成Log4jLog
new Log4jLog(context.getLogger(name));
上述過(guò)程最好與log4j2的原生方式對(duì)比著看,見(jiàn)log4j2的原生方式
commons-logging與logback集成
需要的jar包
jcl-over-slf4j (替代了commons-logging,下面詳細(xì)說(shuō)明)
slf4j-api
logback-core
logback-classic
對(duì)應(yīng)的maven依賴(lài)是:
<dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.1.3</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.3</version> </dependency>
2 使用案例
首先在類(lèi)路徑下編寫(xiě)logback的配置文件logback.xml,簡(jiǎn)單如下:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <root level="DEBUG"> <appender-ref ref="STDOUT" /> </root> </configuration>
使用方式:
private static Log logger=LogFactory.getLog(LogbackTest.class); public static void main(String[] args){ if(logger.isTraceEnabled()){ logger.trace("commons-logging-jcl trace message"); } if(logger.isDebugEnabled()){ logger.debug("commons-logging-jcl debug message"); } if(logger.isInfoEnabled()){ logger.info("commons-logging-jcl info message"); } }
完全是用commons-logging的API來(lái)完成日志編寫(xiě)
3 使用案例分析
logback本身的使用其實(shí)就和slf4j綁定了起來(lái),現(xiàn)在要想指定commons-logging的底層log實(shí)現(xiàn)是logback,則需要2步走
- 第一步: 先將commons-logging底層的log實(shí)現(xiàn)轉(zhuǎn)向slf4j (jcl-over-slf4j干的事)
- 第二步: 再根據(jù)slf4j的選擇底層日志原理,我們使之選擇上logback
這樣就可以完成commons-logging與logback的集成。即寫(xiě)著commons-logging的API,底層卻是logback來(lái)進(jìn)行輸出
然后來(lái)具體分析下整個(gè)過(guò)程的源碼實(shí)現(xiàn):
1 先看下jcl-over-slf4j都有哪些內(nèi)容(它可以替代了commons-logging)
如下圖
這就是jcl-over-slf4j的大致內(nèi)容
這里可以與commons-logging原生包中的內(nèi)容進(jìn)行下對(duì)比。原生包中的內(nèi)容如下:
1.1 commons-logging中的Log接口和LogFactory類(lèi)等
這是我們使用commons-logging編寫(xiě)需要的接口和類(lèi)
1.2 去掉了commons-logging原生包中的一些Log實(shí)現(xiàn)和默認(rèn)的LogFactoryImpl
只有SLF4JLog實(shí)現(xiàn)和SLF4JLogFactory
2 獲取獲取LogFactory的過(guò)程
jcl-over-slf4j包中的LogFactory和commons-logging中原生的LogFactory不一樣,jcl-over-slf4j中的LogFactory直接限制死,是SLF4JLogFactory,源碼如下:
public abstract class LogFactory { static LogFactory logFactory = new SLF4JLogFactory(); //略 }
3 根據(jù)LogFactory獲取Log的過(guò)程
這就需要看下jcl-over-slf4j包中的SLF4JLogFactory的源碼內(nèi)容:
Log newInstance; Logger slf4jLogger = LoggerFactory.getLogger(name); if (slf4jLogger instanceof LocationAwareLogger) { newInstance = new SLF4JLocationAwareLog((LocationAwareLogger) slf4jLogger); } else { newInstance = new SLF4JLog(slf4jLogger); }
可以看到其實(shí)是用slf4j的LoggerFactory先創(chuàng)建一個(gè)slf4j的Logger實(shí)例(這其實(shí)就是單獨(dú)使用logback的使用方式,見(jiàn)logback原生案例)。
然后再將這個(gè)Logger實(shí)例封裝成common-logging定義的Log接口實(shí)現(xiàn),即SLF4JLog或者SLF4JLocationAwareLog實(shí)例。
所以我們使用的commons-logging的Log接口實(shí)例都是委托給slf4j創(chuàng)建的Logger實(shí)例(slf4j的這個(gè)實(shí)例又是選擇logbakc后產(chǎn)生的,即slf4j產(chǎn)生的Logger實(shí)例最終還是委托給logback中的Logger的)
結(jié)尾
這篇講解commons-logging與jul、log4j1、log4j2、logback的集成原理,內(nèi)容很長(zhǎng)了,就把slf4j與上述四者的集成放到下一篇文章,更多關(guān)于jcl與jul log4j1 log4j2 logback日志系統(tǒng)集成的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- logback的AsyncAppender高效日志處理方式源碼解析
- Spring?boot?整合Logback過(guò)程示例解析
- Java?ASM使用logback日志級(jí)別動(dòng)態(tài)切換方案展示
- slf4j與jul、log4j1、log4j2、logback的集成原理
- jdk-logging?log4j?logback日志系統(tǒng)實(shí)現(xiàn)機(jī)制原理介紹
- slf4j?jcl?jul?log4j1?log4j2?logback各組件系統(tǒng)日志切換
- 完整的logback配置示例ELK整合包含生成json日志
- logback?OutputStreamAppender高效日志輸出源碼解析
相關(guān)文章
Java的MyBatis框架中實(shí)現(xiàn)多表連接查詢(xún)和查詢(xún)結(jié)果分頁(yè)
這篇文章主要介紹了Java的MyBatis框架中實(shí)現(xiàn)多表連接查詢(xún)和查詢(xún)結(jié)果分頁(yè),借助MyBatis框架中帶有的動(dòng)態(tài)SQL查詢(xún)功能可以比普通SQL查詢(xún)做到更多,需要的朋友可以參考下2016-04-04JAVA為什么要使用封裝及如何封裝經(jīng)典實(shí)例
這篇文章主要給大家介紹了關(guān)于JAVA為什么要使用封裝及如何封裝的相關(guān)資料,封裝就是將屬性私有化,提供公有的方法訪問(wèn)私有屬性,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10SSH框架網(wǎng)上商城項(xiàng)目第13戰(zhàn)之Struts2文件上傳功能
這篇文章主要為大家詳細(xì)介紹了SSH框架網(wǎng)上商城項(xiàng)目第13戰(zhàn)之Struts2文件上傳功能的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-06-06java實(shí)現(xiàn)文件讀寫(xiě)與壓縮實(shí)例
這篇文章主要介紹了java實(shí)現(xiàn)文件讀寫(xiě)與壓縮實(shí)例,有助于讀者加深對(duì)文件操作的理解,需要的朋友可以參考下2014-07-07淺談Spring如何解決循環(huán)依賴(lài)的問(wèn)題
這篇文章主要介紹了淺談Spring如何解決循環(huán)依賴(lài)的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09解決Idea啟動(dòng)Spring Boot很慢的問(wèn)題
這篇文章主要介紹了解決Idea啟動(dòng)Spring Boot很慢的問(wèn)題,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-12-12Java實(shí)現(xiàn)簡(jiǎn)單連連看游戲
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)單連連看游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05Java微服務(wù)分布式調(diào)度Elastic-job環(huán)境搭建及配置
Elastic-Job在配置中提供了JobEventConfiguration,支持?jǐn)?shù)據(jù)庫(kù)方式配置,會(huì)在數(shù)據(jù)庫(kù)中自動(dòng)創(chuàng)建JOB_EXECUTION_LOG和JOB_STATUS_TRACE_LOG兩張表以及若干索引,來(lái)記錄作業(yè)的相關(guān)信息2023-02-02