您现在的位置是:主页 > news > 日照社保网站开发中什么意思/网络营销促销方案
日照社保网站开发中什么意思/网络营销促销方案
admin2025/6/14 14:16:22【news】
简介日照社保网站开发中什么意思,网络营销促销方案,b2c网站建设流程,房屋设计平面图0. 许久没听Tank了 日志框架统一解决方案(mvn.exclude) slf4j门面设计整合spring的日志方案 qos.slf4j、apache.commons-logging 均是 统一日志接口基本上都是 qos.slf4j apache.log4j2 / qos.logbackslf4j 整合 spring的日志方案的图还有意思,盗过来看看 原来适…
日照社保网站开发中什么意思,网络营销促销方案,b2c网站建设流程,房屋设计平面图0. 许久没听Tank了
日志框架统一解决方案(mvn.exclude) slf4j门面设计整合spring的日志方案 qos.slf4j、apache.commons-logging 均是 统一日志接口基本上都是 qos.slf4j apache.log4j2 / qos.logbackslf4j 整合 spring的日志方案的图还有意思,盗过来看看
原来适…
0. 许久没听Tank了
日志框架统一解决方案(mvn.exclude)
slf4j门面设计整合spring的日志方案
- qos.slf4j、apache.commons-logging 均是 统一日志接口
- 基本上都是 qos.slf4j + apache.log4j2 / qos.logback
- slf4j 整合 spring的日志方案的图还有意思,盗过来看看
原来适配spring这一块的逻辑走的是SPI
1. 静态绑定 与 SPI
-
通过 lombok 引入的 slf4j 版本有点旧,不小心就遇到静态绑定的 “古老的”方案
-
slf4j 1.8+ 改成了 JDK6 所推崇的 SPI
-
静态绑定,简单说就是在第三方实现库(例如 logback)中放接口库(org.slf4j…XxxBinder)的代码来引入自己的实现,放个图就懂了
- slf4j.LoggerFactory -> 第三方日志框架.LoggerFactory -> Logger
2. slf4j 静态绑定 logback
package org.slf4j;public final class LoggerFactory {// 注意:slf4j.LoggerFactory 并没有实现 ILoggerFactory 接口// slf4j.LoggerFactory 是用来 获取 第三方厂商的ILoggerFactory 的public static Logger getLogger(Class<?> clazz) {// step into ...Logger logger = getLogger(clazz.getName());if (DETECT_LOGGER_NAME_MISMATCH) {Class<?> autoComputedCallingClass = Util.getCallingClass();if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", logger.getName(),autoComputedCallingClass.getName()));Util.report("See " + LOGGER_NAME_MISMATCH_URL + " for an explanation");}}return logger;}public static Logger getLogger(String name) {// step into ...// 先获取 LoggerFactoryILoggerFactory iLoggerFactory = getILoggerFactory();// step into ...// 再获取 Loggerreturn iLoggerFactory.getLogger(name);}public static ILoggerFactory getILoggerFactory() {if (INITIALIZATION_STATE == UNINITIALIZED) {synchronized (LoggerFactory.class) {if (INITIALIZATION_STATE == UNINITIALIZED) {INITIALIZATION_STATE = ONGOING_INITIALIZATION;performInitialization();}}}switch (INITIALIZATION_STATE) {// 初始化成功后case SUCCESSFUL_INITIALIZATION:// step into ...// 第三方厂商会有一个 jar/org/slf4j/impl/StaticLoggerBinder 这样子的类路径// slf4j 1.7 版本的做法:由第三方类通过 实现绑定类 来做到静态绑定return StaticLoggerBinder.getSingleton().getLoggerFactory();case NOP_FALLBACK_INITIALIZATION:return NOP_FALLBACK_FACTORY;case FAILED_INITIALIZATION:throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);case ONGOING_INITIALIZATION:// support re-entrant behavior.// See also http://jira.qos.ch/browse/SLF4J-97return SUBST_FACTORY;}throw new IllegalStateException("Unreachable code");}
}-------// 此时是在 第三方的jar目录中(这里使用 logback-classic 演示)
package org.slf4j.impl;public class StaticLoggerBinder implements LoggerFactoryBinder {// step into ...// 3. logback 初始化 loggerFactory、logger// public class LoggerContext extends ContextBase implements ILoggerFactory, LifeCycle// 可见: LoggerContext is a ILoggerFactory// 看看 默认的LoggerFactory 的构造private LoggerContext defaultLoggerContext = new LoggerContext();private StaticLoggerBinder() {defaultLoggerContext.setName(CoreConstants.DEFAULT_CONTEXT_NAME);}private static StaticLoggerBinder SINGLETON = new StaticLoggerBinder();public static StaticLoggerBinder getSingleton() {return SINGLETON;}// 这意味着 LoggerContext(LoggerFactory) 是1个单例private final ContextSelectorStaticBinder contextSelectorBinder = ContextSelectorStaticBinder.getSingleton();static {// step into ...SINGLETON.init();}void init() {try {try {// 4. 读取日志配置文件// step into autoConfig() ...new ContextInitializer(defaultLoggerContext).autoConfig();} catch (JoranException je) {Util.report("Failed to auto configure default logger context", je);}// logback-292if (!StatusUtil.contextHasStatusListener(defaultLoggerContext)) {StatusPrinter.printInCaseOfErrorsOrWarnings(defaultLoggerContext);}contextSelectorBinder.init(defaultLoggerContext, KEY);initialized = true;} catch (Exception t) { // see LOGBACK-1159Util.report("Failed to instantiate [" + LoggerContext.class.getName() + "]", t);}}public ILoggerFactory getLoggerFactory() {if (!initialized) {// 如果没有完成初始化就需要获取1个LoggerFactory,则返回默认的LoggerFactoryreturn defaultLoggerContext;}if (contextSelectorBinder.getContextSelector() == null) {throw new IllegalStateException("contextSelector cannot be null. See also " + NULL_CS_URL);}return contextSelectorBinder.getContextSelector().getLoggerContext();}}
3. logback 初始化 loggerFactory、logger
package ch.qos.logback.classic;public class LoggerContext extends ContextBase implements ILoggerFactory, LifeCycle {// 单例的根节点final Logger root;private Map<String, Logger> loggerCache;// LoggerFactory 构造public LoggerContext() {super();this.loggerCache = new ConcurrentHashMap<String, Logger>();this.loggerContextRemoteView = new LoggerContextVO(this);// 初始化Logger根节点this.root = new Logger(Logger.ROOT_LOGGER_NAME, null, this);this.root.setLevel(Level.DEBUG);// 缓存Logger根节点loggerCache.put(Logger.ROOT_LOGGER_NAME, root);initEvaluatorMap();size = 1;this.frameworkPackages = new ArrayList<String>();}public final Logger getLogger(final Class<?> clazz) {return getLogger(clazz.getName());}@Overridepublic final Logger getLogger(final String name) {if (name == null) {throw new IllegalArgumentException("name argument cannot be null");}// 直接返回 Logger 根节点// if we are asking for the root logger, then let us return it without// wasting timeif (Logger.ROOT_LOGGER_NAME.equalsIgnoreCase(name)) {return root;}int i = 0;Logger logger = root;// check if the desired logger exists, if it does, return it// without further ado.Logger childLogger = (Logger) loggerCache.get(name);// if we have the child, then let us return it without wasting timeif (childLogger != null) {return childLogger;}// if the desired logger does not exist, them create all the loggers// in between as well (if they don't already exist)String childName;while (true) {// 循环获取(并缓存)下一层级的Logger,直至当前类的Logger// 层级按照包的分隔符(.)来分隔// 当找到当前类层级的logger即返回int h = LoggerNameUtil.getSeparatorIndexOf(name, i);if (h == -1) {childName = name;} else {childName = name.substring(0, h);}// move i left of the last pointi = h + 1;synchronized (logger) {childLogger = logger.getChildByName(childName);if (childLogger == null) {childLogger = logger.createChildByName(childName);loggerCache.put(childName, childLogger);incSize();}}logger = childLogger;if (h == -1) {return childLogger;}}}final void noAppenderDefinedWarning(final Logger logger) {if (noAppenderWarning++ == 0) {// TODO 有说法!!!getStatusManager().add(new WarnStatus("No appenders present in context [" + getName() + "] for logger [" + logger.getName() + "].", logger));}}}
4. 读取日志配置文件
// ch.qos.logback.classic.util.ContextInitializer#autoConfigpublic void autoConfig() throws JoranException {StatusListenerConfigHelper.installIfAsked(loggerContext);// 从默认的文件中获取有效的路径// step into ...URL url = findURLOfDefaultConfigurationFile(true);if (url != null) {configureByResource(url);} else {Configurator c = EnvUtil.loadFromServiceLoader(Configurator.class);if (c != null) {try {c.setContext(loggerContext);c.configure(loggerContext);} catch (Exception e) {throw new LogbackException(String.format("Failed to initialize Configurator: %s using ServiceLoader", c != null ? c.getClass().getCanonicalName() : "null"), e);}} else {BasicConfigurator basicConfigurator = new BasicConfigurator();basicConfigurator.setContext(loggerContext);basicConfigurator.configure(loggerContext);}}}// ch.qos.logback.classic.util.ContextInitializer#findURLOfDefaultConfigurationFilepublic URL findURLOfDefaultConfigurationFile(boolean updateStatus) {ClassLoader myClassLoader = Loader.getClassLoaderOfObject(this);URL url = findConfigFileURLFromSystemProperties(myClassLoader, updateStatus);if (url != null) {return url;}// final public static String TEST_AUTOCONFIG_FILE = "logback-test.xml";url = getResource(TEST_AUTOCONFIG_FILE, myClassLoader, updateStatus);if (url != null) {return url;}// final public static String GROOVY_AUTOCONFIG_FILE = "logback.groovy";url = getResource(GROOVY_AUTOCONFIG_FILE, myClassLoader, updateStatus);if (url != null) {return url;}// final public static String AUTOCONFIG_FILE = "logback.xml";return getResource(AUTOCONFIG_FILE, myClassLoader, updateStatus);}