pc端宣传网站开发做+淘宝客最大的网站是叫什么

web/2025/10/5 4:53:15/文章来源:
pc端宣传网站开发,做+淘宝客最大的网站是叫什么,微信小商店分销系统,哪个网站可以做会计分录阅读推荐程序员跳槽时机已到#xff0c;闲聊中面试官无意泄题SpringBoot作为日常开发利器#xff0c;开箱即用#xff0c;大量的star等已经成为节省开发的重要框架之一#xff0c;但是各个框架的star中引入的日志框架却不尽相同#xff0c;有的是log4j#xff0c;有的是s…阅读推荐程序员跳槽时机已到闲聊中面试官无意泄题SpringBoot作为日常开发利器开箱即用大量的star等已经成为节省开发的重要框架之一但是各个框架的star中引入的日志框架却不尽相同有的是log4j有的是slf4j这导致我们在引入多个框架的star的时候往往会引入多个日志框架每一个日志框架彼此效率不尽相同那么我们能不能做到在项目中仅引入一个统一的日志框架呢本篇我们就来探索SpringBoot如何实现统一日志操作为什么需要日志首先我们需要明白日志的作用是什么--即用来在程序运行过程中将我们需要的信息打印出来便于我们在调试中查找和观察。在JAVA中存在很多常见的日志框架如JUL、JCL、Jboss-logging、log4j、logback、slf4j等这么多日志框架我们该如何选择日志门面与日志实现在日志框架选型之前我们先了解一个概念什么是日志门面日志门面,不是具体的日志解决方案,它只服务于各种各样的日志系统允许最终用户在部署其应用时使用其所希望的日志实现来使用日志功能。而日志实现则是基于对应的日志门面的规范来实现的具体日志功能的框架常见的日志门面与日志实现关系如下:每一种日志框架输出信息的效率也不尽相同而我们日常开发使用的框架中往往都会引入一个日志框架来辅助输出框架信息然而框架之间由于历史迭代原因及框架性能等问题选择的日志框架也不一样常见的框架与默认选择的日志系统关系如下:由于历史迭代原因JCL和jboss-logging日志框架基本已经很久没有更新了不太适合作为现在框架的主流选择那么剩下的选择中log4j、slf4j是使用最多的然而由于log4j的输出性能问题log4j的作者选择重新编写了一个日志门面--Slf4j并且编写了基于Slf4j的日志实现--logback其输出信息的效率远超log4j解决了log4j遗留下的性能问题所以在SpringBoot框架中默认也选择了Slf4j来作为默认日志框架slf4j的使用现在我们来看看slf4j的使用,引入maven依赖:org.slf4j slf4j-api 1.7.28按照slf4j官方的说法日志记录方法的调用不应该来直接调用日志的实现类而是调用日志抽象层里面的实现方法获取通过日志工厂创建的日志实例即可输出对应的日志:import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class HelloWorld { public static void main(String[] args) { Logger logger LoggerFactory.getLogger(HelloWorld.class);[图片上传中...(slf4j日志输出过程.png-6f5073-1583207284091-0)] logger.info(Hello World); }}这里我们注意到了一点使用slf4j的输出日志的时候我们也引入了logback这个基于slf4j日志门面实现的具体日志输出框架如果不指定具体的日志输出实现将会找不到具体的日志输出实例slf4j的日志输出过程如图所示:slf4j日志输出过程从图中可以看到应用程序调用了slf4j的api接口以后具体的实现则是由slf4j日志门面找到对应的日志的系统来实现日志输出解决多框架日志不统一问题现在我们再回到日志统一的问题上前面已经了解了开发常用的框架如Spring、mybatis等使用的框架都是框架开发者自己选择的如果我们每个框架就引入一个日志系统并且最终需要打印日志的时候会出现使用n种日志系统平台并且每一种的日志打印的格式、内容和性能都需要手动控制不仅让项目变大而且增大了项目复杂度对性能也有很大的影响那么我们该如何让所有的开源框架统一使用Slf4j来输出呢我们来看下slf4j官方给我们的方案如图所示:sfl4j适配日志从图中我们可以看出来官方的方案是针对不同的日志框架开发了一套适配兼容的框架与之对应使用这些兼容jar来替代原来的日志框架即可例如log4j日志框架与之对应的就是log4j-over-slf4j.jar并且常见的日志框架slf4j团队都实现了一套与之对应的基于slf4j的兼容框架关系如下:日志框架slf4j兼容框架log4jlog4j-over-slf4jcommons loggingjcl-over-slf4jjava.util.loggingjui-to-slf4jSpringBoot如何处理日志关系在使用SpringBoot的时候我们会发现官方默认使用的是spring‐boot‐starter‐logging这个starter来引入日志系统的我们展开该依赖的依赖图如下SpringBoot处理日志关系可以看到spring‐boot‐starter‐logging这个starter中引入了四个日志实例的依赖分别是logback和我们前面提到的日志兼容jar的依赖并且最终引入了slf4j的日志门面的依赖实现了统一日志处理。但是为什么兼容jar引入后就能解决日志输出的问题呢难道兼容包有什么神奇的黑科技吗其实不然我们随便展开其中的几个兼容日志jar的包名如图日志兼容包的包名关系原来这些日志兼容包的包名与原来的日志框架的包名完全一样并且完全按照slf4j的方式实现了一套和以前一样的API这样依赖这些日志框架的开源框架在运行的时候查找对应包名下的class也不会报错但熟悉java类加载机制的都知道两个jar的包名以及使用的class都一样的话加载会出现异常我们进入spring‐boot‐starter‐logging的pom依赖中一探究竟最后在maven依赖中发现了端倪如Spring框架使用的是commons-logging而在spring-boot-starter-logging中将spring的日志依赖排除如下org.springframework spring‐core commons‐logging commons‐logging 这样spring框架在运行时使用的时候使用的就是兼容jar中的日志实例了SpringBoot成功的完成了一次日志系统统一的偷天换日操作。slf4j的桥接原理通过查看SpringBoot的日志处理我们可以大致总结如下几步操作:1、将系统中其他日志框架先排除出去2、用中间包来替换原有的日志框架3、我们导入slf4j其他的实现通过以上的操作即可完成日志系统的统一但是我们开始有了新的疑惑slf4j是怎么做到的自动查找对应的实现日志并且完成了日志的正常打印操作的呢这个就要涉及到slf4j的桥接原理我们先来看看slf4j源码中关于日志调用相关的代码://slf4j日志调用过程相关的代码//根据名称获取日志实例public static Logger getLogger(String name) { ILoggerFactory iLoggerFactory getILoggerFactory(); return iLoggerFactory.getLogger(name);}//获取日志实例工厂并且完成日志实例的查找与初始化操作 public static ILoggerFactory getILoggerFactory() { if (INITIALIZATION_STATE UNINITIALIZED) { INITIALIZATION_STATE ONGOING_INITIALIZATION; //查找实现类 performInitialization(); } ... return StaticLoggerBinder.getSingleton().getLoggerFactory(); ... }可以看到整个过程中是通过StaticLoggerBinder.getSingleton() 来进行初始化日志工厂操作而StaticLoggerBinder这个类是从哪来的呢我们发现StaticLoggerBinder类并不存在于slf4j的jar中而是通过查找org/slf4j/impl/StaticLoggerBinder.class类的路径来发现具体的实现类代码如下://设置默认的查找日志实例的StaticLoggerBinder路径private static String STATIC_LOGGER_BINDER_PATH org/slf4j/impl/StaticLoggerBinder.class;private static Set findPossibleStaticLoggerBinderPathSet() { ....... paths ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH); ......}这个时候我们就该思考一个问题如果我们同时存在了多个StaticLoggerBinder 时会加载哪一个呢熟悉java类加载机制可知类加载器会按照一定的顺序逐个扫描jar包目录并且加载出来所以先被类加载器扫描的StaticLoggerBinder会优先被加载具体的加载顺序如下:1.$java_home/lib 目录下的java核心api2.$java_home/lib/ext 目录下的java扩展jar包3.java -classpath/-Djava.class.path所指的目录下的类与jar包4.$CATALINA_HOME/common目录下按照文件夹的顺序从上往下依次加载5.$CATALINA_HOME/server目录下按照文件夹的顺序从上往下依次加载6.$CATALINA_BASE/shared目录下按照文件夹的顺序从上往下依次加载7.项目/WEB-INF/classes下的class文件8.项目/WEB-INF/lib下的jar文件根据slf4j桥接原理改造logger我们都知道平时使用slf4j输出日志的时候往往获取Logger实例来进行日志打印但是Logger仅仅支持本地日志不支持分布式环境的日志而在slfj中有LogBean实例可以支持分布式日志包含了链路相关信息那么我们是否可以改造slf4j的桥接过程使得我们可以灵活的使用本地日志或者分布式日志呢首先我们先看看我们需要实现的需求:logger和logbean结合,统一日志入口logbean降低代码侵入性无缝替换第三方框架中的日志,根据需求加入到分布式日志中想要实现这个功能有以下两个思路实现:1.我们通过自定义appender基于logback的appender进行扩展可以实现分别输出本地日志以及分布式日志但是缺陷在于appender扩展性不高很多参数信息获取不到例如上下文信息等2.我们通过实现Logger接口用来将Logger和LogBean聚合在一起从而实现LogBean集成到Logger中同样此种方式的缺陷在于对于第三方框架日志我们无能为力无法直接替换使用并且在使用的时候需要使用自定义的LogFactory第一种思路我们可以看出来局限性太高灵活度不够接下来我们尝试使用第二种方案实现聚合Logger和LogBean对外公开统一的api进行日志输出使用:public class CustomLogger implements LocationAwareLogger { private Logger logger; //提供getLogger方法获取logger public static LoggerFacade getLogger(Class clazz) { LoggerFacade loggerFacade new LoggerFacade(); loggerFacade.logger LoggerFactory.getLogger(clazz); return loggerFacade; } ... //打印本地日志的同时 输出到logbean中 Override public void warn(String msg) { logger.warn(msg); appendExtra(msg, Level.WARN); } ...... public void appendExtra(String str, Level level) { String date DateFormatUtils.format(new Date(), yyyy-MM-dd HH:mm:ss); //获取上下文通过上下文判断如果存在则获取分布式环境的LogBean实例 ThreadContext threadContext ContextContainer.retrieveServiceContext(); if (threadContext ! null) { LogBean logBean threadContext.getLogBean(); if (logBean ! null) { logBean.getInner().getExtra().add(date level.toString() simpleName(getName()) - str); } } }}接下来我们可以替换slf4j的实现修改为我们自定义的CustomerLogger内部调用logback的日志本地输出而通过前面桥接原理可以知道slf4j具体桥接获取实例的过程是通过LoggerFactory来获取那么我们来尝试修改LoggerFactory的代码实现替换为CustomerLogger实例public class CustomLoggerFactory implements ILoggerFactory { private static CustomLoggerFactory customLoggerFactory; public static CustomLoggerFactory getInstance(LoggerContext loggerContext) { if (customLoggerFactory null) { customLoggerFactory new CustomLoggerFactory(loggerContext); } return customLoggerFactory; } //logback的LoggerFactory实现 private LoggerContext loggerContext; public CustomLoggerFactory(LoggerContext loggerContext) { this.loggerContext loggerContext; } //返回CustomLogger Override public Logger getLogger(String name) { ch.qos.logback.classic.Logger logger loggerContext.getLogger(name); return CustomLogger.getLogger(logger); } public LoggerContext getLoggerContext() { return loggerContext; } Override public ILoggerFactory getLoggerFactory() { if (!initialized) { return defaultLoggerContext; } if (contextSelectorBinder.getContextSelector() null) { throw new IllegalStateException( contextSelector cannot be null. See also NULL_CS_URL); } LoggerContext loggerContext contextSelectorBinder.getContextSelector().getLoggerContext(); return CustomLoggerFactory.getInstance(loggerContext); }}由以上替换后,项目中通过LoggerFactory获取的到logger对象 就替换成了CustomLogger对象了从而实现了降低侵入将Logger与LogBean整合的效果结语Hi~ o(▽)ブ 整理了约100G的面试、学习资料但是呢篇幅有限。若你有此需求那便可免费分享下载在简信发送“面试”或 点击此链接获取资源下载方式下载吧。网盘上百G资源java面试题详解java视频及资料

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/87168.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

企业网站建设板块茂名网站开发公司

条件(Conditionals) 条件: 条件提供了语言的流控制,否则就是纯粹的静态语言。提供的条件有导入、混入、函数以及更多。下面的例子纯粹示例,并不是使用建议 if / else if / else 这没什么好说的,跟一般的语言一致,i…

营销网站建设佛山专业做淘宝网站

文章目录 首先是主线程 其次是一个程序 通过一个QThread来放入程序 进阶一点: 手动开启关闭线程俩个线程 其实QT中的thread(线程)是很容易的 首先是主线程 #include "mainwindow.h" #include "ui_mainwindow.h"#include <QDebug>MainWindow::MainWin…

网站建设 说明网站制作案例

学习一款软件&#xff0c;我个人建议是先学习怎么用&#xff0c;然后是学习怎么用的好&#xff0c;再研究源码。 上一篇文章详细描述了我们该如何安装虚幻5引擎&#xff1a; UnrealEngine学习(01)&#xff1a;安装虚幻引擎https://blog.csdn.net/zuodingquan666/article/deta…

找网络公司建网站的流程沈阳定制型网站建设

微信公众号&#xff1a;趣编程ACE关注可了解更多的.NET日常实战开发技巧&#xff0c;如需源码 请公众号后台留言 源码;[如果觉得本公众号对您有帮助&#xff0c;欢迎关注].Net6下集成微服务网关-Ocelot网关常见功能1&#xff1a;路由 routing2: 请求聚合3&#xff1a;身份验证和…

cms网站开发涉及的知识中国建筑app下载

简介&#xff1a;从汽车行业的变化&#xff0c;我们即可初步看出芯片的重要性&#xff0c;那么&#xff0c;芯片对汽车行业的发展具体有哪些重要影响呢&#xff1f; 根据全球汽车咨询机构Auto Forecast Solutions统计的数据&#xff0c;截至10月10日&#xff0c;由于芯片短缺&…

福州网站seo做玩网站怎么上传图片

在之前的例子里&#xff0c;由于Atlas客户端在调用Web Services方法时总是使用了Sys.Net.ServiceMethod类&#xff0c;因此始终使用了HTTP POST方法与服务器端进行交互。POST方法有其好处&#xff0c;不过GET方法也自有其价值。我们在使用Atlas进行Web Services调用时&#xff…

中职教材 网站建设石林县工程建设个体交易网站

摘要&#xff1a;class&#xff0c;成员函数&#xff0c;成员变量&#xff0c;类的大小&#xff0c;this 指针 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。 C是基于面向对象的&#xff0c;关注的是对象…

淄博网站建设网宽办公室装修效果图简约大气

https://www.runoob.com/python/python-built-in-functions.html https://www.runoob.com/python3/python3-function.html

房地产 网站 案例oppo软件商店下载

HTML5 在不使用插件的情况下&#xff0c;也可以原生的支持音视频格式文件的播放&#xff0c;当然&#xff0c;支持的格式是有限的。 1、video标签 1.1、video标签的语法 <video src"文件地址" controls"controls"></video> video标签的内部…

如何在国外网站上做外贸网站页面权重

文章目录 Spring Cloud服务注册与发现EurekaServer 启动服务注册服务发现 NacosServer启动 (nacos2.2.0)服务注册服务发现服务集群命名空间配置中心集群搭建 负载均衡RPC远程过程调用Feign使用 网关路由断言工厂网关过滤工厂跨域处理全局跨域配置单个微服务跨域配置 限流 熔断 …

丹东淘宝做网站上海旅游必去景点推荐

接触了百度地图开发平台半个月了&#xff0c;这2天试着模仿了微信给好友发送位置功能&#xff0c;对百度地图的操作能力又上了一个台阶我在实现这个功能的时候&#xff0c;遇到一些困难&#xff0c;可能也是别人将会遇到的困难&#xff0c;特在此列出1、在微信发送功能中&#…

公司网站设计策划案杭州正规企业网站建设

毫不负责任的说&#xff0c;你和数据科学家最大的鸿沟&#xff0c;就差一个SQL语言&#xff1a;)入门后&#xff0c;后面的事情就简单了为了帮大家尽快入门Hive SQL、学会提数和分析&#xff0c;实现在大数据领域大干一场的愿望&#xff0c;帮你准备好了数据&#xff0c;准备好…

怀化市优化办电话seo是什么意思职业

spring防止爬虫Spring Security可以为您做很多事情。 帐户被封锁&#xff0c;密码盐。 但是蛮力阻断剂呢&#xff1f; 那是你必须自己做的。 幸运的是&#xff0c;Spring是一个非常灵活的框架&#xff0c;因此对其进行配置并不是什么大问题。 让我向您展示一些如何针对Grai…

淄博网站外包网站分为哪些结构

题目描述 给定一段“密文”字符串 s,其中字符都是经过“密码本”映射的,现需要将“密文”解密并输出。 映射的规则(a ~ i)分别用(1 ~ 9)表示;(j ~ z)分别用("10*" ~ "26*")表示。 约束:映射始终唯一。 输入描述 “密文”字符串 输出描述 …

厦门网站制作开发收费如何做kindle电子书下载网站

目录 1.监测的背景及意义 1.1监测背景 1.2监测意义 2.系统介绍及特点 2.1系统介绍 2.2系统特点 3.系统设计 3.1监测内容 3.2总体介绍 3.3详细设计 3.3.1垂直度监测 3.3.2水平位移、沉降监测 3.3.3环境监测 3.3.4应力应变监测 3.3.5裂缝监测 3.3.6云平台综合在线…

个人博客网站开发的背景上海软件定制开发

在Linux系统下&#xff0c;这个虚拟内存就被叫做swap。Linux swap分区是有限制的。在安装操作系统的时候&#xff0c;安装向导会提示用户需要创建多少的SWaP空间。通常情况下&#xff0c;SWaP比较合适的大小为物理内存的1-2倍。1. 早期的linux对虚拟内存的限制linux2.2以前的内…

外贸建站哪家公司好东莞整站优化推广公司找火速

点击蓝字关注我们我相信很多人都遇到选择的事情&#xff0c;比较正常的就是&#xff0c;我拿了两个offer要如何选择。用下面这段C代码挺好的&#xff0c;你可以自己加上自己喜欢的判断。#include<stdio.h> #include<stdlib.h> #include<time.h>int main() {i…

淄博网站建设培训班中国建设通网站

目录 1.概述2.结构3.实现3.1.子系统类3.2.外观类3.3.测试 4.优缺点5.使用场景6.源码解析 1.概述 &#xff08;1&#xff09;有些人可能炒过股票&#xff0c;但其实大部分人都不太懂&#xff0c;这种没有足够了解证券知识的情况下做股票是很容易亏钱的&#xff0c;刚开始炒股肯…

seo网站快速ps网站页面设计教程

文章目录 RocketMQ可视化工具1.github上下载2.修改参数3.运行4.打包5.出错6.解决7.重试8.再解决9.很奇怪运行没错&#xff0c;但是测试错啦10.不想深究&#xff0c;直接跳过测试11.展示成功 RocketMQ可视化工具 1.github上下载 下载地址 https://github.com/apache/rocketmq-…

各大搜索引擎网站登录入口学校网站建设有限公司

import React, { useState } from react;// 定义一个简单的函数式组件 function Counter() {// 使用 useState hook 来创建一个状态变量 count&#xff0c;并提供修改该状态的函数 setCountconst [count, setCount] useState(0);// 在点击按钮时增加计数器的值const increment…