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

日照社保网站开发中什么意思/天津百度优化

日照社保网站开发中什么意思,天津百度优化,和县网站开发,上海做公司网站多少钱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);}
http://www.lbrq.cn/news/1097515.html

相关文章:

  • 免费ppt资源网站/免费b站推广网站入口
  • 如何破解网站后台/麒麟seo外推软件
  • 网站制作费计入什么科目/百度下载并安装
  • 郑州做优惠券网站的公司/品牌seo推广
  • wordpress 4.0 文章标题翻译插件/常熟seo关键词优化公司
  • 百度哪个网站做贸易/指数运算法则
  • 杭州高端响应式网站建设/深圳网络推广
  • 给教育类做网站/在线优化网站
  • 四川省人民政府网站官网/百度推广登录首页
  • 三亚网站建设公司/建网站要多少钱
  • 杭州集团网站建设/丹东seo推广优化报价
  • 苏州园区教育网/郑州网络seo公司
  • 成都网站建设四川冠辰科技/合肥网站快速优化排名
  • h5网站开发流程/网站大全
  • 本网站正在建设图片/推广方式怎么写
  • 医疗网站建设案例/网站收录量是什么意思
  • word做网站连接/企业在线培训系统
  • 阿里云突发性能适用于做网站吗/网站seo软件
  • 网站开发属于什么模式/西安今日头条新闻
  • 义乌网站推广/百度知道首页官网
  • 龙华附近网站建设公司/活动推广软文范例
  • 做网站要会什么/十大放黄不登录不收费
  • python 网站开发 linux/app拉新一手渠道商
  • 哪个网站可以学做蛋糕/合肥seo网络营销推广
  • 网上注册网站要钱吗/昆明网站seo服务
  • 上海网站建设多少费用/今日头条官网
  • 什么网站有题目做/seo分析seo诊断
  • 池州网站制作公司/怎么网络推广自己业务
  • 新乡平原新区建设局网站/什么文案容易上热门
  • 网站建设补贴/百度网站入口
  • 从ZooKeeper到KRaft:Kafka架构演进与无ZooKeeper部署指南
  • 【Python】常见模块及其用法
  • JavaScript,发生异常,try...catch...finally处理,继续向上层调用者传递异常信息
  • uniapp app打包流程
  • 理解向量及其运算-AI云计算数值分析和代码验证
  • Vue组件之间通信