SpringBoot源码解析(六):打印Banner
SpringBoot源码系列文章
SpringBoot源码解析(一):SpringApplication构造方法
SpringBoot源码解析(二):引导上下文DefaultBootstrapContext
SpringBoot源码解析(三):启动开始阶段
SpringBoot源码解析(四):解析应用参数args
SpringBoot源码解析(五):准备应用环境
SpringBoot源码解析(六):打印Banner
目录
- 前言
- 一、入口
- 二、Banner接口类
- 1、打印Banner开关
- 三、打印Banner过程
- 1、console和log模式
- 2、四种Banner对象
- 2.1、图片Banner
- 2.2、文字Banner
- 2.2、备用Banner
- 2.3、默认Banner
- 总结
前言
在前文中,我们深入解析了SpringBoot启动时应用环境的准备过程
。接下来将深入介绍启动Banner
打印的具体实现及流程。
SpringBoot版本2.7.18
SpringApplication的run方法的执行逻辑如下,本文将详细介绍第5小节:打印启动Banner
// SpringApplication类方法
public ConfigurableApplicationContext run(String... args) {// 记录应用启动的开始时间long startTime = System.nanoTime();// 1.创建引导上下文,用于管理应用启动时的依赖和资源DefaultBootstrapContext bootstrapContext = createBootstrapContext();ConfigurableApplicationContext context = null;// 配置无头模式属性,以支持在无图形环境下运行// 将系统属性 java.awt.headless 设置为 trueconfigureHeadlessProperty();// 2.获取Spring应用启动监听器,用于在应用启动的各个阶段执行自定义逻辑SpringApplicationRunListeners listeners = getRunListeners(args);// 启动开始方法(发布开始事件、通知应用监听器ApplicationListener)listeners.starting(bootstrapContext, this.mainApplicationClass);try {// 3.解析应用参数ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);// 4.准备应用环境,包括读取配置文件和设置环境变量ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);// 配置是否忽略 BeanInfo,以加快启动速度configureIgnoreBeanInfo(environment);// 5.打印启动BannerBanner printedBanner = printBanner(environment);// 6.创建应用程序上下文context = createApplicationContext();// 设置应用启动的上下文,用于监控和管理启动过程context.setApplicationStartup(this.applicationStartup);// 7.准备应用上下文,包括加载配置、添加 Bean 等prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);// 8.刷新上下文,完成 Bean 的加载和依赖注入refreshContext(context);// 9.刷新后的一些操作,如事件发布等afterRefresh(context, applicationArguments);// 计算启动应用程序的时间,并记录日志Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);}// 10.通知监听器应用启动完成listeners.started(context, timeTakenToStartup);// 11.调用应用程序中的 `CommandLineRunner` 或 `ApplicationRunner`,以便执行自定义的启动逻辑callRunners(context, applicationArguments);}catch (Throwable ex) {// 12.处理启动过程中发生的异常,并通知监听器handleRunFailure(context, ex, listeners);throw new IllegalStateException(ex);}try {// 13.计算应用启动完成至准备就绪的时间,并通知监听器Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);listeners.ready(context, timeTakenToReady);}catch (Throwable ex) {// 处理准备就绪过程中发生的异常handleRunFailure(context, ex, null);throw new IllegalStateException(ex);}// 返回已启动并准备就绪的应用上下文return context;
}
一、入口
// 5.打印启动Banner
Banner printedBanner = printBanner(environment);// 打印启动 Banner 的方法,根据配置的 Banner 模式选择打印方式
private Banner printBanner(ConfigurableEnvironment environment) {// 如果 Banner 模式被设置为 OFF,则不打印 Banner,直接返回 nullif (this.bannerMode == Banner.Mode.OFF) {return null;}// 确定资源加载器。如果当前实例的 resourceLoader 不为空,则使用它;否则创建一个默认的资源加载器ResourceLoader resourceLoader = (this.resourceLoader != null) ? this.resourceLoader: new DefaultResourceLoader(null);// 创建 Banner 打印器,负责加载和打印 BannerSpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(resourceLoader, this.banner);// 根据 Banner 模式决定打印到日志还是控制台if (this.bannerMode == Mode.LOG) {// 如果 Banner 模式为 LOG,则将 Banner 打印到日志中return bannerPrinter.print(environment, this.mainApplicationClass, logger);}// 默认情况下(CONSOLE 模式),将 Banner 打印到标准输出(控制台)return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
}
二、Banner接口类
// 一个用于以编程方式输出 Banner 的接口类
@FunctionalInterface
public interface Banner {// 将 Banner 输出到指定的打印流void printBanner(Environment environment, Class<?> sourceClass, PrintStream out);// 用于配置 Banner 的模式枚举enum Mode {// 禁用 Banner 的打印OFF,// 将 Banner 输出到 System.outCONSOLE,// 将 Banner 输出到日志文件LOG}
}
1、打印Banner开关
- 默认情况是打印到
控制台
- 可以通过
properties或yml
设置关闭打印Banner
spring.main.banner-mode=off
上一节有讲spring.main
开头的属性会绑定到SpringApplication
对象上,这样就可以通过配置文件的属性来决定Banner的打印模式。
三、打印Banner过程
1、console和log模式
- console控制台模式,默认设置
// SpringApplicationBannerPrinter类方法
Banner print(Environment environment, Class<?> sourceClass, PrintStream out) {// 根据提供的环境信息获取横幅。Banner banner = getBanner(environment);// 将横幅打印到指定的输出流中。banner.printBanner(environment, sourceClass, out);// 返回一个 PrintedBanner 对象,包含打印的横幅和源类信息。return new PrintedBanner(banner, sourceClass);
}
- log日志文件模式,通过在配置文件中设置
spring.main.banner-mode=log
,可以将应用启动Banner输出到日志文件中
// SpringApplicationBannerPrinter类方法
Banner print(Environment environment, Class<?> sourceClass, Log logger) {// 根据提供的环境信息获取横幅。Banner banner = getBanner(environment);try {logger.info(createStringFromBanner(banner, environment, sourceClass));}catch (UnsupportedEncodingException ex) {logger.warn("Failed to create String for banner", ex);}// 返回一个 PrintedBanner 对象,包含打印的横幅和源类信息。return new PrintedBanner(banner, sourceClass);
}
- log模式就是获取
打印流内容转换为字符串
,然后由log日志打印罢了
两种方式都会返回一个PrintedBanner
对象,主要是为以后在应用上下文中注册为Bean或供其他组件使用做准备。
2、四种Banner对象
- 图片和文本横幅组合的Banners
- 备用Banner
- 默认Banner
// SpringApplicationBannerPrinter类方法// 默认Banner
private static final Banner DEFAULT_BANNER = new SpringBootBanner();// 根据当前环境获取适当的横幅(Banner)
private Banner getBanner(Environment environment) {// 创建一个 Banners 对象,用于存储图片和文本横幅Banners banners = new Banners();// 尝试获取图片横幅,并将其添加到 Banners 中(如果非空)banners.addIfNotNull(getImageBanner(environment));// 尝试获取文本横幅,并将其添加到 Banners 中(如果非空)banners.addIfNotNull(getTextBanner(environment));// 如果至少包含一个横幅,则返回组合的 Banners 对象if (banners.hasAtLeastOneBanner()) {return banners;}// 如果没有任何横幅但存在备用横幅,则返回备用横幅if (this.fallbackBanner != null) {return this.fallbackBanner;}// 如果没有任何横幅,则返回默认横幅// Banner DEFAULT_BANNER = new SpringBootBanner();return DEFAULT_BANNER;
}
Banners
对象内部持有多个Banner
实现类,遍历调用Banner的printBanner
方法
2.1、图片Banner
- 尝试根据环境信息获取图片横幅(Image Banner)
- 环境变量
spring.banner.image.location
用于指定图片路径;如果未设置,则默认加载路径为banner.gif
、banner.jpg
或banner.png
(按顺序查找)。
private Banner getImageBanner(Environment environment) {// 从环境变量中获取横幅图片的路径// String BANNER_IMAGE_LOCATION_PROPERTY = "spring.banner.image.location";String location = environment.getProperty(BANNER_IMAGE_LOCATION_PROPERTY);// 如果路径不为空,尝试加载对应的资源if (StringUtils.hasLength(location)) {Resource resource = this.resourceLoader.getResource(location);// 如果资源存在,返回对应的 ImageBanner 对象return resource.exists() ? new ImageBanner(resource) : null;}// 如果未指定路径,尝试加载默认图片横幅文件// String[] IMAGE_EXTENSION = { "gif", "jpg", "png" };for (String ext : IMAGE_EXTENSION) {Resource resource = this.resourceLoader.getResource("banner." + ext);// 如果找到存在的文件资源,返回对应的 ImageBanner 对象if (resource.exists()) {return new ImageBanner(resource);}}// 如果没有找到任何图片横幅资源,返回 nullreturn null;
}
控制台效果
2.2、文字Banner
- 尝试根据环境信息获取文本横幅(Text Banner)
- 环境变量
spring.banner.location
用于指定文本路径;如果未设置,则默认加载路径为banner.txt
。
private Banner getTextBanner(Environment environment) {// 获取横幅的路径,优先使用环境变量中的配置,如果没有配置则使用默认路径// String BANNER_LOCATION_PROPERTY = "spring.banner.location";// String DEFAULT_BANNER_LOCATION = "banner.txt";String location = environment.getProperty(BANNER_LOCATION_PROPERTY, DEFAULT_BANNER_LOCATION);// 使用 ResourceLoader 加载指定路径的资源Resource resource = this.resourceLoader.getResource(location);try {// 检查资源是否存在,且路径中不包含 "liquibase-core"(防止加载到不相关的资源)if (resource.exists() && !resource.getURL().toExternalForm().contains("liquibase-core")) {// 如果资源有效,返回对应的 ResourceBanner 对象return new ResourceBanner(resource);}} catch (IOException ex) {// 忽略异常,可能是资源加载时出错或路径无效// 在这里不抛出异常,而是返回 null,表示没有有效的横幅资源}// 如果资源无效或发生异常,返回 nullreturn null;
}
控制台效果
2.2、备用Banner
SpringApplicationBannerPrinter
对象的备用Banner属性fallbackBanner
是由SpringApplication
对象的私有属性banner
传递而来的。
- 可以在SpringBoot启动类中通过调用
SpringApplication
的setBanner
方法直接设置自定义的Banner
对象
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication app = new SpringApplication(Application.class);// 设置全局备用横幅app.setBanner((environment, sourceClass, out) -> {out.println("===== 全局备用横幅 =====");out.println(" 默认横幅已启用 ");out.println("=====================");});app.run(args);}
}
控制台效果
2.3、默认Banner
如果未设置自定义文字图片Banner或备用Banner,SpringBoot将使用默认的启动横幅(SpringBootBanner
)作为显示内容。
// 默认的 Banner 实现,用于打印 "Spring" 的启动横幅,和版本信息
class SpringBootBanner implements Banner {// 预定义的 ASCII 艺术横幅,每行为一个数组元素private static final String[] BANNER = { "", " . ____ _ __ _ _"," /\\\\ / ___'_ __ _ _(_)_ __ __ _ \\ \\ \\ \\","( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\"," \\\\/ ___)| |_)| | | | | || (_| | ) ) ) )", " ' |____| .__|_| |_|_| |_\\__, | / / / /"," =========|_|==============|___/=/_/_/_/" };// 固定的 Spring Boot 标识符,用于横幅输出private static final String SPRING_BOOT = " :: Spring Boot :: ";// 横幅固定宽度,用于计算 padding 的空格数private static final int STRAP_LINE_SIZE = 42;/*** 输出横幅到指定的 PrintStream(如控制台或日志)。*/@Overridepublic void printBanner(Environment environment, Class<?> sourceClass, PrintStream printStream) {// 遍历并打印每一行 ASCII 艺术横幅for (String line : BANNER) {printStream.println(line);}// 获取 Spring Boot 的版本信息String version = SpringBootVersion.getVersion();// 如果版本信息不为空,则格式化为 "(vX.X.X)"version = (version != null) ? " (v" + version + ")" : "";// 构造 padding 空格,使横幅版本号对齐StringBuilder padding = new StringBuilder();while (padding.length() < STRAP_LINE_SIZE - (version.length() + SPRING_BOOT.length())) {padding.append(" ");}// 打印 Spring Boot 标识符和版本信息,使用 ANSI 输出样式printStream.println(AnsiOutput.toString(AnsiColor.GREEN, // 绿色输出 Spring Boot 标识符SPRING_BOOT, AnsiColor.DEFAULT, // 恢复默认颜色padding.toString(), // 填充的空格AnsiStyle.FAINT, // 微弱样式(淡化显示版本信息)version // 版本号));// 添加空行用于分隔横幅和其他输出printStream.println();}
}
控制台效果
总结
本文全面解析了SpringBoot启动横幅的实现原理、打印流程及自定义方法,介绍了文本横幅(默认路径为banner.txt
,可通过spring.banner.location
配置)、图片横幅(默认路径为banner.gif
、banner.jpg
或banner.png
,可通过spring.banner.image.location
配置)、备用横幅和默认横幅的使用,帮助开发者灵活运用横幅机制提升项目启动体验。
相关文章:
SpringBoot源码解析(六):打印Banner
SpringBoot源码系列文章 SpringBoot源码解析(一):SpringApplication构造方法 SpringBoot源码解析(二):引导上下文DefaultBootstrapContext SpringBoot源码解析(三):启动开始阶段 SpringBoot源码解析(四):解析应用参数args Sp…...
【计算机网络】实验6:IPV4地址的构造超网及IP数据报
实验 6:IPV4地址的构造超网及IP数据报 一、 实验目的 加深对IPV4地址的构造超网(无分类编制)的了解。 加深对IP数据包的发送和转发流程的了解。 二、 实验环境 • Cisco Packet Tracer 模拟器 三、 实验内容 1、了解IPV4地址的构造超网…...
easy excel 生成excel 文件
导包 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.3</version> </dependency> 内容 List<类> limspjreport 值; String fileName sdf.format(new Date()) "-…...
Ajax:回忆与节点
一点回忆 面对我的Ajax学习,实现前后端交互,最开始我采用的使用网络寻找intellij IDEA Ultimate破解方法,然后最终成功,然后按照相关教程配置java ee项目,然后中间又去配置了Tomcat服务器,然后又去学习了一…...
Python+OpenCV系列:Python和OpenCV的结合和发展
PythonOpenCV系列:Python和OpenCV的结合和发展 **引言****Python语言的发展****1.1 Python的诞生与发展****1.2 Python的核心特性与优势****1.3 Python的应用领域** **OpenCV的发展****2.1 OpenCV的起源与发展****2.2 OpenCV的功能特性****2.3 OpenCV的应用场景** *…...
Ubuntu20.04 由源码编译安装opencv3.2 OpenCV
Ubuntu20.04 由源码编译安装opencv3.2.0 获取 opencv 及opencv_contrib源代码 创建目录以存放opencv及opencv_contrib源代码 mkdir ~/opencv3.2.0 cd ~/opencv3.2.0获取opencv源代码并切换到对应tag git clone https://github.com/opencv/opencv.git cd opencv git checkou…...
A058-基于Spring Boot的餐饮管理系统的设计与实现
🙊作者简介:在校研究生,拥有计算机专业的研究生开发团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看项目链接获取⬇️,记得注明来意哦~🌹 赠送计算机毕业设计600个选题ex…...
RDIFramework.NET CS敏捷开发框架 SOA服务三种访问(直连、WCF、WebAPI)方式
1、介绍 在软件开发领域,尤其是企业级应用开发中,灵活性、开放性、可扩展性往往是项目成功的关键因素。对于C/S项目,如何高效地与后端数据库进行交互,以及如何提供多样化的服务访问方式,是开发者需要深入考虑的问题。…...
Linux——命名管道及日志
linux——进程间通信及管道的应用场景-CSDN博客 文章目录 目录 文章目录 前言 一、命名管道是什么? 理解: 2、编写代码 makefile 管道封装成类,想用中管道时只需要调用实例化 读端 写端 日志 1、日志是什么? 2、日志有什么&#x…...
Flink 常见面试题
1、Flink 的四大特征(基石) checkpoin基于Chandy-Lamport算法实现了分布式一致性快照提供了一致性的语义 state丰富的StateAPI time实现了Watermark机制,乱序数据处理,迟到数据容忍 window开箱即用的滚动,滑动会话窗口…...
rtc-pcf8563 0-0051: low voltage detected, date/time is not reliable
解决方法: 1、先测量pcf8563电源电压,是否满足要求。 2、pcf8563首次操作。第一次读取pcf8563的时间,未初始化,非法,芯片门槛电压检测配置不合理。使用hwclock命令写入一次,即可解决。 hwclock -f /dev/…...
(简单5步实现)部署本地AI大语言模型聊天系统:Chatbox AI + grok2.0大模型
摘要: 本文将指导您如何部署一个本地AI大语言模型聊天系统,使用Chatbox AI客户端应用和grok-beta大模型,以实现高效、智能的聊天体验。 引言: 由马斯克X-AI发布的Grok 2大模型以其卓越的性能超越了GPT4.0。Grok模型支持超长文本…...
MAUI APP开发蓝牙协议的经验分享:与跳绳设备对接
在开发MAUI应用程序时,蓝牙协议的应用是一个重要的环节,尤其是在需要与外部设备如智能跳绳进行数据交换的场景中。以下是我在开发过程中的一些经验和心得,希望能为你的项目提供帮助。 1. 蓝牙协议基础 蓝牙协议是无线通信的一种标准&#x…...
最新版Node.js下载安装及环境配置教程
目录 初识:Node.js 一、下载:Node.js 二、安装:Node.js 1.下载【node.js】压缩包安装文件 2.解压下载的安装包 3.打开解压的【node-v22.11.0-x64】文件夹 4.双击启动安装程序 5.点击【Next】 6.勾选【I accept the terms in the Lic…...
51c自动驾驶~合集39
我自己的原文哦~ https://blog.51cto.com/whaosoft/12707676 #DiffusionDrive 大幅超越所有SOTA!地平线DiffusionDrive:生成式方案或将重塑端到端格局? 近年来,由于感知模型的性能持续进步,端到端自动驾驶受到了来…...
单链表基础操作
文章目录 abstract定义结点结构初始化链表遍历链表求表长查找结点根据序号查找结点根据值查找结点 插入结点首尾位置插入一般位置插入(通用插入)找到尾元素|尾指针相关操作 删除结点 abstract 单链表是一种简单的动态数据结构,它由一系列结点组成,每个结…...
Asp.net MVC在VSCore中的页面的增删改查(以Blog项目为例),用命令代码
在VSCore中的页面的增删改查(以Blog项目为例) 1.创建项目(无解决方案)复杂项目才需要 dotnet new mvc -o Blog2.控制器 BlogsController.cs 控制器(Controller)名字和视图(View)中的文件名要一模一样 u…...
【Leecode】Leecode刷题之路第66天之加一
题目出处 66-加一-题目出处 题目描述 个人解法 思路: todo代码示例:(Java) todo复杂度分析 todo官方解法 66-加一-官方解法 方法1:找出最长的后缀9 思路: 代码示例:(Java&#…...
使用 VLC 在本地搭建流媒体服务器 (详细版)
提示:详细流程 避坑指南 Hi~!欢迎来到碧波空间,平时喜欢用博客记录学习的点滴,欢迎大家前来指正,欢迎欢迎~~ ✨✨ 主页:碧波 📚 📚 专栏:音视频 目录 借助VLC media pl…...
Ubuntu 常用解压与压缩命令
.zip文件 unzip FileName.zip # 解压 zip DirName.zip DirName # 将DirName本身压缩 zip -r DirName.zip DirName # 压缩,递归处理,将指定目录下的所有文件和子目录一起压缩 zip DirName.zip DirName 行为: 只压缩 DirName 目录本身ÿ…...
【深度学习】四大图像分类网络之AlexNet
AlexNet是由Alex Krizhevsky、Ilya Sutskever(均为Hinton的学生)和Geoffrey Hinton(被誉为”人工智能教父“,首先将反向传播用于多层神经网络)在2012年ImageNet图像分类竞赛中提出的一种经典的卷积神经网络。AlexNet在…...
Day1——GitHub项目共同开发
MarkDowm解释 Markdown是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成结构化的HTML代码。Markdown的目的是让文档的编写和阅读变得更加容易,同时也不失HTML的强大功能。以下是Markdown的一些基本概念和用法&a…...
基于PHP的香水销售系统的设计与实现
摘 要 时代科技高速发展的背后,也带动了经济的增加,人们对生活质量的要求也不断提高。香水作为一款在人际交往过程中,给对方留下良好地第一印象的产品,在生活中也可以独自享受其为生活带来的点缀。目前香水市场体量庞大ÿ…...
A-star算法
算法简介 A*(A-star)算法是一种用于图形搜索和路径规划的启发式搜索算法,它结合了最佳优先搜索(Best-First Search)和Dijkstra算法的思想,能够有效地寻找从起点到目标点的最短路径。A*算法广泛应用于导航、…...
前端用原生js下载File对象文件,多用于上传附件时,提交之前进行点击预览,或打开本地已经选择待上传的附件列表
用于如上图场景,已经点击选择了将要上传的文件,在附件列表里面用户希望点击下载文件,以核实自己是否选中了需要上传的文件,此刻就需要 用到下面的方法: // 下载File对象文件 downloadByFileObject(file, { fileName }…...
服务器记录所有用户docker操作,监控删除容器/镜像的人
文章目录 使用场景安装auditd添加docker审计规则设置监控日志大小与定期清除查询 Docker 操作日志查看所有用户,所有操作日志查看特定用户的 Docker 操作查看所有用户删除容器/镜像日志过滤特定时间范围内日志 使用场景 多人使用的服务器,使用的docker …...
关于使用天地图、leaflet、ENVI、Vue工具实现 前端地图上覆盖上处理的农业地块图层任务
1.项目框架搭建 项目地址:Webgis: 一个关于webgis、天地图、Leaflet、Vue、数据库的学习框架。 ①git到本地,vscode打开。 ② 配置后端 搜索下载MySQL插件(前提:电脑中装有MySQL才可应用)。 连接数据库。 配置基本…...
基于yolov4深度学习网络的排队人数统计系统matlab仿真,带GUI界面
目录 1.算法仿真效果 2.算法涉及理论知识概要 3.MATLAB核心程序 4.完整算法代码文件获得 1.算法仿真效果 matlab2022a仿真结果如下(完整代码运行后无水印): 仿真操作步骤可参考程序配套的操作视频。 2.算法涉及理论知识概要 在现代社会…...
用 React 编写一个笔记应用程序
这篇文章会教大家用 React 编写一个笔记应用程序。用户可以创建、编辑、和切换 Markdown 笔记。 1. nanoid nanoid 是一个轻量级和安全的唯一字符串ID生成器,常用于JavaScript环境中生成随机、唯一的字符串ID,如数据库主键、会话ID、文件名等场景。 …...
如何离线安装dockerio
如何离线安装dockerio 一、下载Docker离线安装包二、上传离线安装包三、解压安装包四、复制文件到系统目录五、配置Docker服务六、设置文件权限并重新加载配置七、启动Docker服务八、设置开机自启动九、验证安装Docker是一个开源的容器化平台,用于开发、发布和运行应用程序。离…...
app网站怎么制作/百度云资源
给定一幅彩色图像,它由$mtimes n$的像素$A[1cdots m,1cdots n]$构成,每个像素是一个红绿蓝$(RGB)$亮度的三元组。假定我们希望轻度压缩这幅图像。具体地,我们希望从每一行中删除一个像素,使得图像变窄一个像素。 为了避免影响视觉…...
无锡高端网站制作/深圳关键词优化公司哪家好
为什么80%的码农都做不了架构师?>>> <p>logger的驱动程序为文件logger.c, 位于内核driver/staging/android目录.</p><p>从最后一行<code>device_initcall</code>(<code>logger_init</code>)入口, 内核在启动…...
金融直播室网站建设/网络推广产品公司
前言 腾讯手机游戏在登录时会使用QQ或微信授权登录,此时可配置权限,包含游戏账号信息、游戏好友关系等。那么如何对腾讯游戏进行权限管理呢,有如下2种方法,分别为登录授权时配置和进入设置配置。 登录授权时配置 QQ 在QQ授权登…...
JSP做网站起到的作用/我要安装百度
熟悉Java并发编程的程序员应该对于volatile,synchronized关键都不陌生,这两个关键字是并发编程的基础,在之前笔者看过很多关于volatile关键字的解析博客,讲述的也比较详细,但是感觉不是很全面,今天总结了一…...
怎么做网站策划/最近有哪些新闻
sort方法接收一个函数作为参数,这里嵌套一层函数用来接收对象属性名,其他部分代码与正常使用sort方法相同. var arr [{name:zopp,age:0},{name:gpp,age:18},{name:yjj,age:8} ];function compare(property){return function(a,b){var value1 a[proper…...
番禺做网站600元/b2b平台网站
in 判断元素是否存在于容器当中 list1 [1, 2, 3] tuple1 (1, 2, 3) set1 {1, 2, 3} print(3 in list1) # True print(3 in tuple1) # True print(3 in set1) # True 如果要判断是否在set当中,要注意被判断的元素必须可以保存在set当中,如果是列表,字典,集合,则不能判断 …...