(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怎…

户用光伏电站的管理包括哪些内容?需要怎么做?

户用光伏电站在运行后需要进行一系列的管理工作&#xff0c;包括安全、运行、质量和数据等等&#xff0c;从而保证电站的安全、经济、高效运行。 1.安全管理 光伏电站的安全管理是非常重要的&#xff0c;包括电站的防雷、防火、防盗等措施&#xff0c;以及电站内部的安全管理…

实践:读取html文本提取相应内容按照格式导出到excel中

最近在做一个需求&#xff0c;需要将html文本中的内容提取出来&#xff0c;然后导出到excel里面&#xff0c;实现交代情景&#xff0c;html文本中存在许多标签&#xff0c;且很乱&#xff0c;因此需要之间将标签里面的文本提取出来&#xff0c;再进行处理。 ............String…

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

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

多智能体强化学习--理论与算法

目录标题 基础概念MADDPG的actor和critic网络actor网络&#xff1a;**critic网络&#xff1a;** MAPPO的actor和critic网络actor网络&#xff1a;critic网络&#xff1a; QMix (QMIX)VDN (Value Decomposition Networks) 参考博士论文&#xff1a;基于强化学习的多智能体协同关…

go数据操作-MySQL

1.快速入门 下载依赖 go get -u github.com/go-sql-driver/mysql使用MySQL驱动 func Open(driverName, dataSourceName string) (*DB, error)Open打开一个dirverName指定的数据库&#xff0c;dataSourceName指定数据源&#xff0c;一般至少包括数据库文件名和其它连接必要的…

【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…

springboot 文件上传

前言 用户访问当前系统,将自己本地计算机中文件通过浏览器上传到当前系统所在的服务器过程中称之为文件的上传 具体思路 1.文件上传 文件上传: 用户将本地计算机中文件上传到服务器过程称之为文件上传 2.文件上传开发思路: a.提供一张上传页面 提交方式必须:post enctype属…

Oracle RMAN全备脚本(正式测试可行)

Oracle RMAN全备脚本 正式环境测试可行 请参考。 run{ allocate channel c1 type disk maxpiecesize20G; allocate channel c2 type disk maxpiecesize20G; allocate channel c3 type disk maxpiecesize20G; allocate channel c4 type disk maxpiecesize20G; crosscheck arch…

创建表与删除表(六)

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

【python基础】—函数式编程三个基本函数map()/filter()/reduce()

文章目录 前言一、map()函数二、filter()函数三、reduce()函数 前言 map()、filter()、reduce()是python内置函数&#xff0c;它们提供了一种便捷的方式来处理可迭代对象中的元素&#xff0c;这些函数在许多编程任务中非常有用&#xff0c;包括数据转换&#xff0c;筛选和累积…

​LeetCode解法汇总2670. 找出不同元素数目差数组

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 描述&#xff1a; 给你一个下…