(2)SpringBoot学习——芋道源码

Spring Boot 的自动配置

1.概述

EmbeddedWebServerFactoryCustomizerAutoConfiguration 类

@Configuration // <1.1>
@ConditionalOnWebApplication // <2.1>
@EnableConfigurationProperties(ServerProperties.class) // <3.1>
public class  EmbeddedWebServerFactoryCustomizerAutoConfiguration {/*** Nested configuration if Tomcat is being used.*/@Configuration // <1.2>@ConditionalOnClass({ Tomcat.class, UpgradeProtocol.class })public static class TomcatWebServerFactoryCustomizerConfiguration {@Beanpublic TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) {// <3.2>return new TomcatWebServerFactoryCustomizer(environment, serverProperties);}}/*** Nested configuration if Jetty is being used.*/@Configuration // <1.3>@ConditionalOnClass({ Server.class, Loader.class, WebAppContext.class })public static class JettyWebServerFactoryCustomizerConfiguration {@Beanpublic JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) {// <3.3>return new JettyWebServerFactoryCustomizer(environment, serverProperties);}}/*** Nested configuration if Undertow is being used.*/// ... 省略 UndertowWebServerFactoryCustomizerConfiguration 代码/*** Nested configuration if Netty is being used.*/// ... 省略 NettyWebServerFactoryCustomizerConfiguration 代码}
  • ① 配置类
  • ② 条件注解
  • ③ 配置属性

① 配置类
<1.1> 处,在类上添加了 @Configuration 注解,声明这是一个配置类。因为它的目的是自动配置,所以类名以 AutoConfiguration 作为后缀。

<1.2>、<1.3> 处,分别是用于初始化 Tomcat、Jetty 相关 Bean 的配置类。

  • TomcatWebServerFactoryCustomizerConfiguration 配置类,负责创建 TomcatWebServerFactoryCustomizer Bean,从而初始化内嵌的 Tomcat 并进行启动。
  • JettyWebServerFactoryCustomizer 配置类,负责创建
    JettyWebServerFactoryCustomizer Bean,从而初始化内嵌的 Jetty 并进行启动。

结论一:通过 @Configuration 注解的配置类,可以解决“创建哪些 Bean”的问题。

② 条件注解
<2> 处,在类上添加了 @ConditionalOnWebApplication 条件注解,表示当前配置类需要在当前项目是 Web 项目的条件下,才能生效。在 Spring Boot 项目中,会将项目类型分成 Web 项目(使用 SpringMVC 或者 WebFlux)和非 Web 项目。这样我们就很容易理解,为什么 EmbeddedWebServerFactoryCustomizerAutoConfiguration 配置类会要求在项目类型是 Web 项目,只有 Web 项目才有必要创建内嵌的 Web 服务器呀。
<2.1>、<2.2> 处,在类上添加了 @ConditionalOnClass 条件注解,表示当前配置类需要在当前项目有指定类的条件下,才能生效。

  • TomcatWebServerFactoryCustomizerConfiguration 配置类,需要有tomcat-embed-core 依赖提供的 Tomcat、UpgradeProtocol 依赖类,才能创建内嵌的 Tomcat服务器。
  • JettyWebServerFactoryCustomizer 配置类,需要有 jetty-server 依赖提供的 Server、Loader、WebAppContext 类,才能创建内嵌的 Jetty 服务器。
    结论二:通过条件注解,可以解决“满足什么样的条件?”的问题。

③ 配置属性
< 3.1> 处,使用 @EnableConfigurationProperties 注解,让 ServerProperties 配置属性类生效。在 Spring Boot 定义了 @ConfigurationProperties 注解,用于声明配置属性类,将指定前缀的配置项批量注入到该类中。例如 ServerProperties 代码如下:

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerPropertiesimplements EmbeddedServletContainerCustomizer, EnvironmentAware, Ordered {/*** Server HTTP port.*/private Integer port;/*** Context path of the application.*/private String contextPath;// ... 省略其它属性}
  • 通过 @ConfigurationProperties 注解,声明将 server 前缀的配置项,设置到 ServerProperties配置属性类中。

< 3.2>、< 3.3> 处,在创建 TomcatWebServerFactoryCustomizer 和 JettyWebServerFactoryCustomizer 对象时,都会将 ServerProperties 传入其中,作为后续创建的 Web 服务器的配置。也就是说通过修改在配置文件的配置项,就可以自定义 Web 服务器的配置。
结论三:通过配置属性,可以解决“创建的 Bean 的属性?”的问题。

2. 自动配置类

  1. Spring Boot 的 spring-boot-autoconfigure 项目,提供了大量框架的自动配置
  2. 通过 SpringApplication#run(Class<?> primarySource, String… args)方法,启动 Spring Boot 应用的时候,有个非常重要的组件 SpringFactoriesLoader 类,会读取META-INF 目录下的 spring.factories 文件,获得每个框架定义的需要自动配置的配置类。
  3. spring-boot-autoconfigure 项目提供的是它选择的主流框架的自动配置,所以其它框架需要自己实现。

3. 条件注解

在 Spring3.1 版本时,为了满足不同环境注册不同的 Bean ,引入了 @Profile 注解。

@Configuration
public class DataSourceConfiguration {@Bean@Profile("DEV")public DataSource devDataSource() {// ... 单机 MySQL}@Bean@Profile("PROD")public DataSource prodDataSource() {// ... 集群 MySQL}}
  • 在测试环境下,注册单机 MySQL 的 DataSource Bean。
  • 在生产环境下,注册集群 MySQL 的 DataSource
    Bean。

在 Spring4 版本时,提供了 @Conditional 注解,用于声明在配置类或者创建 Bean 的方法上,表示需要满足指定条件才能生效

@Configuration
public class TestConfiguration {@Bean@Conditional(XXXCondition.class) // XXXCondition: 实现Condition 接口,提供具体的条件实现。public Object xxxObject() {return new Object();}
}
  • @ConditionalOnBean:当容器里有指定 Bean 的条件下
  • @ConditionalOnMissingBean:当容器里没有指定 Bean 的情况下
  • @ConditionalOnSingleCandidate:当指定 Bean 在容器中只有一个,或者虽然有多个但是指定首选 Bean
  • @ConditionalOnClass:当类路径下有指定类的条件下
  • @ConditionalOnMissingClass:当类路径下没有指定类的条件下
  • @ConditionalOnProperty:指定的属性是否有指定的值
  • @ConditionalOnResource:类路径是否有指定的值
  • @ConditionalOnExpression:基于 SpEL 表达式作为判断条件
  • @ConditionalOnJava:基于 Java版本作为判断条件
  • @ConditionalOnJndi:在 JNDI 存在的条件下差在指定的位置
  • @ConditionalOnNotWebApplication:当前项目不是 Web 项目的条件下
  • @ConditionalOnWebApplication:当前项目是 Web项 目的条件下

4. 配置属性

Spring Boot 约定读取 application.yaml、application.properties 等配置文件,从而实现创建 Bean 的自定义属性配置,甚至可以搭配 @ConditionalOnProperty 注解来取消 Bean 的创建。

5.自定义 Starter

在一些场景下,需要实现自定义 Starter 来达到自动配置的目的。例如说:

  • 三方框架并没有提供 Starter,比如说 Swagger、XXL-JOB 等。
  • Spring Boot 内置的 Starter 无法满足自己的需求,比如说 spring-boot-starter-jdbc 不提供多数据源的配置。
    在这里插入图片描述
    命名规则
    在这里插入图片描述

5.1 yunai-server-spring-boot-starter 项目

5.1.1 引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>lab-47</artifactId><groupId>cn.iocoder.springboot.labs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>yunai-server-spring-boot-starter</artifactId><dependencies><!-- 引入 Spring Boot Starter 基础库 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>2.2.2.RELEASE</version></dependency></dependencies></project>

5.1.2 YunaiServerProperties

在 cn.iocoder.springboot.lab47.yunaiserver.autoconfigure 包下,创建 YunaiServerProperties 配置属性类,读取 yunai.server 前缀的配置项。代码如下:

@ConfigurationProperties(prefix = "yunai.server")
public class YunaiServerProperties {/*** 默认端口*/private static final Integer DEFAULT_PORT = 8000;/*** 端口*/private Integer port = DEFAULT_PORT;public static Integer getDefaultPort() {return DEFAULT_PORT;}public Integer getPort() {return port;}public YunaiServerProperties setPort(Integer port) {this.port = port;return this;}}

5.1.3 YunaiServerAutoConfiguration

在 cn.iocoder.springboot.lab47.yunaiserver.autoconfigure 包下,创建 YunaiServerAutoConfiguration 自动配置类,在项目中存在 com.sun.net.httpserver.HttpServer 类时,创建 HttpServer Bean,并启动该服务器。代码如下:

@Configuration // 声明配置类
@EnableConfigurationProperties(YunaiServerProperties.class) // 使 YunaiServerProperties 配置属性类生效
public class YunaiServerAutoConfiguration {private Logger logger = LoggerFactory.getLogger(YunaiServerAutoConfiguration.class);@Bean // 声明创建 Bean@ConditionalOnClass(HttpServer.class) // 需要项目中存在 com.sun.net.httpserver.HttpServer 类。该类为 JDK 自带,所以一定成立。public HttpServer httpServer(YunaiServerProperties serverProperties) throws IOException {// 创建 HttpServer 对象,并启动HttpServer server = HttpServer.create(new InetSocketAddress(serverProperties.getPort()), 0);server.start();logger.info("[httpServer][启动服务器成功,端口为:{}]", serverProperties.getPort());// 返回return server;}
}

5.1.4 spring.factories

在 resources 目录下创建,创建 META-INF 目录,然后在该目录下创建 spring.factories 文件,添加自动化配置类为 YunaiServerAutoConfiguration。内容如下:

rg.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.iocoder.springboot.lab47.yunaiserver.autoconfigure.YunaiServerAutoConfiguration

5.2 lab-47-demo 项目

5.2.1 引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>lab-47</artifactId><groupId>cn.iocoder.springboot.labs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>lab-47-demo</artifactId><dependencies><!-- 引入自定义 Starter --><dependency><groupId>cn.iocoder.springboot.labs</groupId><artifactId>yunai-server-spring-boot-starter</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies></project>

5.2.2 配置文件

在 resource 目录下,创建 application.yaml 配置文件,设置 yunai.server.port 配置项来自定义 HttpServer 端口。配置如下:

yunai:server:port: 8888 # 自定义 HttpServer 端口

5.2.3 DemoApplication

创建 DemoApplication.java 类,配置 @SpringBootApplication 注解即可。代码如下:

@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}

5.2.4 测试

执行 DemoApplication#main(String[] args) 方法,启动 Spring Boot 应用。打印日志如下:

2020-02-02 13:03:12.156  INFO 76469 --- [           main] c.i.s.lab47.demo.DemoApplication         : Starting DemoApplication on MacBook-Pro-8 with PID 76469 (/Users/yunai/Java/SpringBoot-Labs/lab-47/lab-47-demo/target/classes started by yunai in /Users/yunai/Java/SpringBoot-Labs)
2020-02-02 13:03:12.158  INFO 76469 --- [           main] c.i.s.lab47.demo.DemoApplication         : No active profile set, falling back to default profiles: default
2020-02-02 13:03:12.873  INFO 76469 --- [           main] c.i.s.l.y.a.YunaiServerAutoConfiguration : [httpServer][启动服务器成功,端口为:8888]
2020-02-02 13:03:12.927  INFO 76469 --- [           main] c.i.s.lab47.demo.DemoApplication         : Started DemoApplication in 1.053 seconds (JVM running for 1.47)
  • YunaiServerAutoConfiguration 成功自动配置 HttpServer Bean,并启动该服务器在 8888 端口

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

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

相关文章

推荐一个好用的旧版本软件安装包下载地址

最近要下载旧版本的mysql和postman&#xff0c;发现官网和其他博客里边提供的地址&#xff0c;要不都非常难找到相应的下载链接&#xff0c;要不就是提供的从别的地方复制过来的垃圾教程&#xff0c;甚至有的下载还要积分&#xff0c;反正是最后都没下载成功&#xff0c;偶然发…

nodejs基于vue奖学金助学金申请系统08ktb

高校奖助学金系统的目的是让使用者可以更方便的将人、设备和场景更立体的连接在一起。能让用户以更科幻的方式使用产品&#xff0c;体验高科技时代带给人们的方便&#xff0c;同时也能让用户体会到与以往常规产品不同的体验风格。 与安卓&#xff0c;iOS相比较起来&#xff0c;…

期末成绩群发给家长

每当学期结束&#xff0c;老师们的邮箱和手机便会被成绩报告单填满。那么&#xff0c;如何高效地将成绩群发给家长呢&#xff1f; 一、邮件还是短信&#xff1f; 首先&#xff0c;选择一个合适的通讯方式是关键。邮件正式且便于附件&#xff0c;但短信更快捷。考虑到大多数家长…

windows平台使用tensorRT部署yolov5详细介绍,整个流程思路以及细节。

目录 Windows平台上使用tensorRT部署yolov5 前言&#xff1a; 环境&#xff1a; 1.为什么要部署&#xff1f; 2.那为什么部署可以解决这个问题&#xff1f;&#xff08;基于tensorRT&#xff09; 3.怎么部署&#xff08;只讨论tensorRT&#xff09; 3.0部署的流程 3.1怎…

UE4学习笔记 FPS游戏制作2 制作第一人称控制器

文章目录 章节目标前置概念Rotator与Vector&#xff1a;roll与yaw与pitch 添加按键输入蓝图结构区域1区域2区域3区域4 章节目标 本章节将实现FPS基础移动 前置概念 Rotator与Vector&#xff1a; Vector是用向量表示方向&#xff0c;UE中玩家的正前方是本地坐标系的(1,0,0)&…

【Linux】信号量

信号量 一、POSIX信号量1、信号量的原理2、信号量的概念&#xff08;1&#xff09;PV操作必须是原子操作&#xff08;2&#xff09;申请信号量失败被挂起等待 3、信号量函数4、销毁信号量5、等待信号量&#xff08;申请信号量&#xff09;6、发布信号量&#xff08;释放信号量&…

20240131在WIN10下配置whisper

20240131在WIN10下配置whisper 2024/1/31 18:25 首先你要有一张NVIDIA的显卡&#xff0c;比如我用的PDD拼多多的二手GTX1080显卡。【并且极其可能是矿卡&#xff01;】800&#xffe5; 2、请正确安装好NVIDIA最新的545版本的驱动程序和CUDA。 2、安装Torch 3、配置whisper http…

仰暮计划|“从米票、肉票、糖果票到肥皂票、煤票、棉花票等,生活里头的方方面面都能用粮票买到”

口述人&#xff1a;牛翠英(女) 整理人&#xff1a;霍芝冉 口述人基本信息&#xff1a;现68岁&#xff0c;河南省安阳市北关区霍家村人&#xff0c;现居河南安阳市区。 奶奶一生辛劳&#xff0c;操持家务&#xff1b;亲眼见证了时代变迁&#xff0c;社会发展&#xff0c;…

docker笔记整理

Docker 安装 添加yum源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 安装docker yum -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin 启动docker systemctl start docker 查看docker状态 s…

09. 异常处理

目录 1、前言 2、常见的异常 3、异常处理try...except...finally 4、异常信息解读 5、raise 6、自定义异常 7、小结 1、前言 在编程中&#xff0c;异常&#xff08;Exception&#xff09;是程序在运行期间检测到的错误或异常状况。当程序执行过程中发生了一些无法继续执…

C languange DGEQRF 示例,link liblapack.a

1.示例源码 #include <stdio.h>int min(int m, int n){ return m<n? m:n;}void print_matrix(double* A, int m, int n, int lda) {for (int i 0; i < m; i){for (int j 0; j < n; j){//printf("%7.4f ", A[i j*lda]);printf("%7.4f, &quo…

创建表与删除表(六)

表的基本操作&#xff08;六&#xff09; 一、创建表 1.1 使用DDL语句创建表 CREATE TABLE 表名(列名 类型,列名 类型......); 示例&#xff1a; 创建一个 employees 表包含雇员 ID &#xff0c;雇员名字&#xff0c;雇员薪水。 create table employees(employee_id int,em…

从创新者到引领者:探索第四范式的AI之旅

大数据产业创新服务媒体 ——聚焦数据 改变商业 如今&#xff0c;人工智能已成为改变世界、驱动各行各业变革的核心源动力。在国内&#xff0c;有一些公司已走在前列&#xff0c;其中就包括北京第四范式智能技术股份有限公司&#xff0c;在AI这个赛道&#xff0c;他是一名创新…

Patch2QL:开源供应链漏洞挖掘和检测的新方向

背景 开源生态的上下游中&#xff0c;漏洞可能存在多种成因有渊源的其它缺陷&#xff0c;统称为“同源漏洞”&#xff0c;典型如&#xff1a; 上游代码复用缺陷。开源贡献者在实现功能相似的模块时&#xff0c;常复用已有模块代码或逻辑&#xff1b;当其中某个模块发现漏洞后…

java:java反编译工具--jd-gui

JD-GUI是一款反编译软件&#xff0c;JD分为JD-GUI、JD-Eclipse两种运行方式&#xff0c;JD-GUI是以单独的程序的方式运行&#xff0c;JD-Eclipse则是以一个Eclipse插件的方式运行。 官方下载地址&#xff1a; https://github.com/java-decompiler/jd-gui/releases 我这边下载…

Unity Shader 滚动进度条效果

Unity Shader 滚动进度条效果 前言项目场景布置导入图片修改场景设置修改图片尺寸即可调整进度 ASE连线 前言 UI要实现一个滚动进度&#xff0c;于是使用Shader制作一个。 项目 场景布置 导入图片 修改一下导入图片的格式&#xff0c;这样才能循环起来 WrapMode改为Repea…

正点原子--STM32中断系统学习笔记(1)

1、什么是中断&#xff1f; 原子哥给出的概念是这样的&#xff1a;打断CPU正常执行的程序&#xff0c;转而处理紧急程序&#xff0c;然后返回原暂停的程序继续运行&#xff0c;就叫中断。 当发生中断时&#xff0c;当前执行的程序会被暂时中止&#xff0c;进而进入中断处理函…

Node: opensslErrorStack: [ ‘error:03000086:digital envelope routines::initialization error‘ ]异常处理

目录 一、问题描述二、问题分析三、解决方案方案一&#xff1a;你可以按照以下步骤来删除 NODE_OPTIONS 环境变量中的 --openssl-legacy-provider 选项&#xff1a;方案二&#xff1a;在package.json更改scripts方案三&#xff1a;降级 Node.js 版本 在进行前端项目开发时&…

Linux+服务器后台运行程序

在Linux服务器直接运行程序&#xff0c;程序运行的时间较长&#xff0c;程序经常会因为网络连接问题异常终止&#xff0c;一直盯着程序运行又费时费力&#xff0c;这时后台运行程序是更好的解决方式。But&#xff0c;如果服务器重启了&#xff0c;那所有进程都断掉了&#xff0…

关于v8垃圾回收机制以及与其相关联的知识点--还没整理版本

对于值类型b来说&#xff0c;就直接释放了其占用的内存&#xff0c;对于引用类型obj来说&#xff0c;销毁的只是变量obj对堆内存地址 1001 的引用&#xff0c;obj的值 { c: 3 } 依然存在于堆内存中。那么堆内存中的变量如何进行回收呢&#xff1f; V8的垃圾回收策略主要是基于…