Spring Cloud基础--Spring Boot
1. Spring Boot 诞生背景
1.1 servlet开发问题(2012年 mike youngstrom【AWS工程师】在spring jira提出)
基于spring原生的Servlet开发太繁琐,需要额外的学习成本,问题如下:
- 需要配置文件如web.xml,不同的Servlet容器的配置文件也不同。
- 需要构建war包部署到Servlet容器。
- 不同的Servlet容器有不同的配置方式,比如端口和线程池。
- ClassLoader 继承机制复杂。
- 监控和管理功能需要在应用外部进行配置。
- 单独配置日志功能。
- 理解ApplicationContext内的各种配置以及继承关系。
1.2 起源想法
Improve Containerless Web Application Architectures(改进无容器的 Web 应用结构)
- 提供一个统一的组件模型,不需要知道Servlet组件模型。
- 统一所有的配置格式,生效于应用和第三方组件,只需要学习这个配置模型。
- 从main函数执行将会简化应用的启动和关闭。
- 一个更简单的纯java类加载层次结构。
- 简单的开发工具(不需要复杂的IDE来构建WAR包,也不用部署到Servlet容器)。
1.3 如今的SpringBoot对应的功能
Spring Boot创始人Phil Webb针对上面的问题以及一些其他关联Issure,决定启动Spring Boot新项目,而不是在Spring Core 模块里修改。
- 内置Servlet容器,提供统一的容器抽象【如Tomcat、Jetty、Undertow和Netty实现类】。
- 对所有的组件的配置项,可以使用相同的格式在application.properties或application.yml中配置。
- 提供了SpringApplication用于直接运行Spring应用,无须关注ApplicationContext的构造。
- 只存在一个ClassLoader,不会像单独的Servlet容器那样拥有独立的ClassLoader。
- 内置Servlet容器,直接执行main方法即可,无须构造WAR包
提示:以上内容可以参见Spring Boot官网概览【overview】中的历史,重点关注其中的特性【Features】。
2. Spring Boot 核心
提示:个人理解SpringBoot的核心就是其核心特性能力产生的根本原因
2.1 WebServer
新版本的SpringBoot使用WebServer来取代原来的内置Servlet容器【EmbeddedWebApplicationContext】,具体工厂类类图如下:
2.2 条件注解
Spring Boot的自动化装配模块 spring-boot-autoconfigure中包含很多第三方依赖的AutoConfiguration自动化装配类。
为了保证这些AutoConfiguration只在特定场景下生效,我们有了条件注解。
条件注解 | 作用 | 条件注解解析类 |
---|---|---|
@ConditionalOnBean | ApplicationContext存在某些Bean时,条件成立 | OnBeanCondition |
@ConditionalOnMissingBean | ApplicationContext不存在某些bean时,条件成立 | OnBeanCondition |
@ConditionalOnSingleCandidate | ApplicationContext中存在且只有一个bean时条件成立 | OnBeanCondition |
@ConditionalOnClass | ClassPath中存在某些Class时,条件成立 | OnClassCondition |
@ConditionalOnMissingClass | classPath中不存在某些Class时,条件成立 | OnClassCondition |
@ConditionalOnCloudPlatform | 在某些云平台(Kubemetes、Heroku、Cloud Foundry)下条件成立 | OnCloudPlatformCondition |
@ConditionalOnExpression | SPEL表达式(spring的el表达式)成立时条件才成立 | OnExpressionCondition |
@ConditionalOnJava | JDK某些版本条件成立,默认Range范围 >= JDK的某个版本 | OnJavaCondition |
@ConditionalOnJndi | JNDI路径下存在时条件才成立 | OnJndiCondition |
@ConditionalOnWebApplication | 在Web环境下条件才成立 | OnWebApplicationCondition |
@ConditionalOnNotWebApplication | 在非Web环境下条件才成立 | OnWebApplicationCondition |
@ConditionalOnProperty | Environment中存在某些配置项时才成立 | OnPropertyCondition |
@ConditionalOnResource | 存在某些资源时条件才成立 | OnResourceCondition |
提示:条件注解仅仅是一个注解,真正的判断逻辑在这些条件注解的解析类内部。
Spring Boot通过spring-context模块中的ConditionEvaluator来使用条件注解去判断是否需要加载自动化配置类。
在AnnotatedBeanDefinitionReader、ClassPathScanningCandidateComponentProvider、ConfigurationClassBeanDefinitionReader、ConfigurationClassParser中使用ConditionEvaluator去判断是否跳过相关配置类。
提示:Condition的子类SpringBootCondition使用模板方法模式,转matches到getMatchOutcome方法。@ConditionalOnBean之类的注解源码引用@Conditional(OnBeanCondition.class)注解。
自定义条件注解的关键就是继承Condition【Spring】或SpringBootCondition【Spring Boot】,实现matches或getMatchOutcome方法