微服务阶段
- JavaSE:面向对象
- MySql + JDBC:持久化存储
- html + css +JavaScript + Jquery + 框架:视图,框架
- JavaWeb:开始独立开发MVC三层架构的网站(原始)
- SSM:框架(简化了我们的开发流程,配置也开始较为复杂)
- war:Tomcat运行
- Spring再简化:SpringBoot - Jar(内嵌Tomcat)- 微服务架构
SpringCloud:
Spring
Spring是一个开源框架,2003年兴起的一个轻量级的Java开发框架。Spring是为了解决企业级应用开发的复杂性而创建的,简化开发
为了降低Java开发的复杂性,Spring采用了以下4种关键策略:
- 1、基于POJO的轻量级和最小侵入性编程
- 2、通过IOC,依赖注入(DI)和面向接口实现松耦合;
- 3、基于切面(AOP)和惯例进行声明式编程
- 4、通过切面和模板减少样式代码
核心思想:约定大于配置!!!
(程序猿)程序 = 数据结构 + 算法(集合框架)
(码农)程序 = 面向对象 + 框架
微服务架构
微服务是一种架构风格,它要求我们在开发一个应用的时候,这个应用必须构建一系列小服务的组合;可以通过http方式进行互通。要说微服务架构,先得说说过去我们的单体应用架构
单体应用架构:
- 所谓单体应用架构(all in one)是指,我们将一个应用的中的所有应用服务都封装在一个应用中。
- 无论是ERP、CRM或是其他什么系统,你都把数据库访问,web访问,等等各个功能放到一个war包内
- 这样做的好处是:易于开发和测试;也十分方便部署;当需要扩展时,只需要将war复制多份,然后放到多个服务器上,再做个负载均衡就可以了。
- 单体应用框架的缺点是:哪怕我要修改一个非常小的地方,我都需要停掉整个服务、重新打包、部署这个应用war包。特别是对于一个大型应用,我们不可能把所有内容放在一个应用里面,我们如何维护、如何分工合作都是问题
微服务架构:
- all in one的架构方式,我们把所有的功能单元放在一个应用里面。然后我们把整个应用部署到服务器上。如果负载能力不行,我们将整个应用进行水平复制,进行扩展,然后在负载均衡。
- 所谓微服务架构,就是打破之前all in one的架构方式,把每个功能元素独立出来。把独立出来的功能元素的动态组合,需要的功能元素才去拿来组合,需要多一些时可以整合多个功能元素。所以微服务架构是对功能元素进行复制,而没有对整个应用复制
- 这样做的好处:
- 1、节省了调用资源
- 2、每个功能元素的服务都是一个可替换的、可独立升级的软件代码
高内聚,低耦合!!!
如何构建微服务
一个大型系统的微服务架构,就像一个复杂交织的神经网络,每一个神经元就是一个功能元素,它们各自完成自己的功能,然后通过http相互请求调用。比如一个电商系统,查缓存、连数据库、浏览页面、结账、支付等服务都是一个个独立的功能服务,都被微化了,它们作为一个个微服务共同构建一个庞大的系统。如果修改其中的一个功能,只需要更新升级其中一个功能服务单元即可。
但是这种庞大的系统架构给部署和运维带来很大的难度。于是,Spring为我们带来了构建大型分布式微服务的全套、全程产品:
- 构建一个个功能独立的微服务应用单元,可以使用SpringBoot,可以帮我们快速构建一个应用;
- 大型分布式网络服务的调用,这部分由Spring Cloud来实现,实现分布式;
- 在分布式中间,进行流式数据计算、批处理,我们有Spring Cloud Data Flow。
- Spring为我们想清楚了整个从开始构建应用到大型分布式应用全流程方案。
第一个SpringBoot程序
官方:提供一个快速生成的网站,IDEA集成了这个网站
- 可以在官网直接下载后,导入idea开发(官网在哪)
- 可以直接使用idea创建一个SpringBoot项目(一般开发直接在IDEA中创建)
官网网址:https://spring.io/projects/spring-boot
进入官网后,点击Spring Initializr 在官网配置好项目后,就可以点击下面的 GENERATE CTRL + 回车 。然后会得到一个项目压缩包,解压后,就可以导入到 idea 中。
如果是在idea工具里面进行配置的话,一定要注意,下载来源不要默认,而要加上阿里云镜像!!!!
后面的过程就和官网配置页面设置一样,选好后,就可以进入到项目中编写了。
package com.blb.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/hello")
public class HelloController {
@GetMapping("/hello")
@ResponseBody
public String hello(){
return "hello,world";
}
}
当我们写好第一个接口后,就可以在本地上跑一下了 成功!!!
细节讲解:
- @RequestMapping():注解映射请求路径
- @GetMapping和@PostMapping
-
从命名约定我们可以看到每个注释都是为了处理各自的传入请求方法类型,即@GetMapping 用于处理请求方法的GET类型,@PostMapping 用于处理请求方法的POST类型等。 -
如果我们想使用传统的@RequestMapping注释实现URL处理程序,那么它应该是这样的: @RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
-
新方法可以简化为: @GetMapping("/get/{id}")
@responseBody注解的作用是:
- 将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。
- 注意:在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据
原理初探
自动配置:
- pom.xml
- spring-boot-dependencies:核心依赖在父工程中
- 我们在写或者引入一些SpringBoot依赖的时候,不需要指定版本,就因为有这些版本仓库
启动器:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
- 启动器就是SpringBoot的启动场景
- 比如spring-boot-starter-web,他就会帮我们自动导入web环境所有的依赖!
- SpringBoot会将所有的功能场景,都变成一个个的启动器
- 我们要使用什么功能,就只需要找到对应的启动器就可以了 starter
主程序:
package com.blb.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
- 注解
- @SpringBootConfiguration:SpringBoot的配置
- @Configuration:Spring配置类
- @Component:说明这也是一个Spring的组件
- @EnableAutoConfiguration:自动配置
- @AutoConfigurationPackage:自动配置包
- @Import({AutoConfigurationPackages.Registrar.class}):自动配置 包注册
- @Import(AutoConfigurationImportSelector.class):自动导入选择
- 获取所有的配置:
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
获取候选的配置:
- 方法getCandidateConfigurations()返回了自动配置类的信息列表,而它通过调用SpringFactoriesLoader.loadFactoryNames()来扫描加载含有META-INF/spring.factories文件的jar包,该文件记录了具有哪些自动配置类
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
META-INF/spring.factories:自动配置的核心文件
所有资源加载到配置类中!
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
结论:SpringBoot所有自动配置都是在启动的时候扫描并加载(spring.factories所有的自动配置类都在这里面,但是不一定生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器了,有了启动器,我们自动装配就会生效,然后就配置成功!)
- 1、SpringBoot在启动的时候,从类路径下
/META-INF/spring.factories 获取指定的值; - 2、将这些自动配置的类导入容器,自动配置就会生效,帮我进行自动配置
- 3、以前我们需要自动配置的东西,现在SpringBoot帮我们做了!
- 4、整个JavaEE,解决方案和自动配置的东西都在
spring-boot-autoconfigure-2.2.0.RELEASE.jar 这个包下 - 5、它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器;
- 6、容器中也会存在非常多的
xxxAutoConfiguration@Bean 的文件,就是这些类给容器中导入了这个场景需要的所有组件;并自动配置。@Configuration,JavaConfig! - 7、有了自动配置类,免去了我们手动编写配置文件的工作了!
SpringApplication.run(主程序类)分析:分析该方法主要分为两部分
- 1、SpringApplication的实例化
- new SpringApplication(主程序类)
- 判断是否web应用
- 加载并保存所有ApplicationContextInitializer(META-INF/spring.factories)
- 加载并保存所有ApplicationListener
- 获取到主程序类
- 2、run方法的执行
- run()
- 回调所有的SpringApplicationRunListener(META-INF/spring.factories)的starting
- 获取ApplicationArguments
- 准备环境和所有监听器(SpringApplicationRunListener)的environmentPrepared
- 打印banner信息
- 创建ioc容器对象
- AnnotationConfigEmbeddedWebApplicationContext(Web环境容器)
- AnnotationConfigApplicationContext(普通环境容器)
SpringApplication:这个类主要做了以下四件事情
- 1、推断应用的类型是普通的项目还是Web项目
- 2、查找并加载所有可用初始化器,设置到initializers属性中
- 3、找出所有的应用程序监听器,设置到listeners属性中
- 4、推断并设置main方法的定义类,找到运行的主类
查看构造器:
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = new HashSet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = this.deduceMainApplicationClass();
}
SpringBoot:配置文件及自动配置原理
配置文件:SpringBoot使用一个全局的配置文件,配置文件名称是固定的
- application.properties
- application.yaml
配置文件的作用:修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了;
YAML
YAML是"YAML Ain’t a Markup Language"(YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言),但为了强调这种语言以数据做为中心,而不是以标记语言为重点,而用反向缩略语重命名。(取自百度百科)
标记语言:以前的配置文件,大多数都是使用xml来配置;比如一个简单的端口配置,我们来对比下yaml和xml
-
yaml配置: server:
port: 8080
name: huake
student:
name: huake
age: 3
studednt: {name: huake, age: 3}
pets:
- cat
- dog
- pig
pets: [cat, dog, pig]
-
xml配置: <server>
<port>8080</port>
</server>
-
properties只能写键值对 name=huake
student.name = huake
student.age = 3
YAML语法
基本语法:
k:(空格) v
以此来表示一对键值对(空格不能省略);以空格的缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。
注意:属性和值的大小写都是十分敏感的。例如:
server:
port: 8080
path: /hello
值的写法:字面量: 普通的值 [数字, 布尔值, 字符串]
k: v
字面量直接写在后面就可以,字符串默认不用加上双引号或者单引号;"" 双引号,不会转义字符串里面的特殊字符,特殊字符会作为本身想表示的意思;
比如:name: "kuang \n shen"
输出:
kuang
shen
yaml可以直接给实体类赋值:
- 首先介绍一下原生的赋值方式:
- 先创建一个类
- @component是spring中的一个注解,它的作用就是实现bean的注入(注册bean)
- @Value是一个赋值注解
- @Autowired是用在JavaBean中的注解,通过byType形式,用来给指定的字段或方法注入所需的外部资源
- 经过测试,我们拿到了实例化后的值;
- 接下来就是通过yaml文件来进行赋值:
-
同样先创建好我们的类 -
在yaml文件进行对应类型赋值 -
最后进行测试,发现数据都得到了 -
打印结果 Person{name='huake',
age=3,
happy=true,
birth=Fri Jan 07 00:00:00 CST 2022,
maps={k1=v1, k2=v2},
lists=[code, music, girl],
dog=Dog{name='旺财', age=3}}
@ConfigurationProperties作用:
- 将配置文件中配置的每一个属性值,映射到这个组件中;
- 告诉SpringBoot将本类中的所有属性和配置文件中国相关的配置进行绑定
- 参数 prefix = “person” (将配置文件中的person下面的所有属性一一对应)
- 只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能
上面采用的方法都是最简单的方式,开发中最常用的;那我们来唠叨一下其他的实现方式,道理都是相通的,写还是那样写;配置文件除了yaml还有我们之前常用的properties,但properties配置文件在写中文的时候,会有乱码,我们需要去IDEA中设置编码格式为UTF-8;
| @ConfigurationProperties | @Value |
---|
功能 | 批量注入配置文件中的属性 | 一个个指定 | 松散绑定(松散语法) | 支持 | 不支持 | SpEL | 不支持 | 支持 | JSR303数据校验 | 支持 | 不支持 | 复杂类型封装 | 支持 | 不支持 |
- cp只需要写一次即可,value则需要每个字段都添加
- 松散绑定:比如我的yaml中写的last-name,这个和lastName是一样的,- 后面跟着的字母默认是大写的。这就是松散绑定
- JSR303数据校验:这个就是我们可以在字段是增加一层过滤器验证,可以保证数据的合法性
- 复杂类型封装,yaml中可以封装对象,使用@Value就不支持
结论:
- 配置yaml和配置properties都可以获取到值,强烈推荐yaml
- 如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用 @Value
- 如果说,我们专门编写了一个JavaBean来和配置文件进行映射,就直接使用 @ConfigurationProperties,不要犹豫!!!
JSR303数据校验(了解即可):
SpringBoot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。
-
我们这里来写个注解让我们的name只能支持Email格式 -
空检查
- @Null 验证对象是否为null
- @NotNull 验证对象是否不为null, 无法查检长度为0的字符串
- @NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
- @NotEmpty 检查约束元素是否为NULL或者是EMPTY.
-
Booelan检查
- @AssertTrue 验证 Boolean 对象是否为 true
- @AssertFalse 验证 Boolean 对象是否为 false
-
长度检查
- @Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内
- @Length(min=, max=) Validates that the annotated string is between
min and max included. -
日期检查
- @Past 验证 Date 和 Calendar 对象是否在当前时间之前
- @Future 验证 Date 和 Calendar 对象是否在当前时间之后
- @Pattern 验证 String 对象是否符合正则表达式的规则(正则表达式)
-
数值检查,建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng为"",Integer为null
- @Min 验证 Number 和 String 对象是否大等于指定的值
- @Max 验证 Number 和 String 对象是否小等于指定的值
- @DecimalMax 被标注的值必须不大于约束中指定的最大值.
这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度 - @DecimalMin 被标注的值必须不小于约束中指定的最小值.
这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度 - @Digits 验证 Number 和 String 的构成是否合法
- @Digits(integer=,fraction=)
验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。 - @Range(min=, max=) Checks whether the annotated value lies between
(inclusive) the specified minimum and maximum. - @Range(min=10000,max=50000,message=“range.bean.wage”) private
BigDecimal wage; - @Valid 递归的对关联对象进行校验,
如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证) - @CreditCardNumber信用卡验证
- @Email 验证是否是邮件地址,如果为null,不进行验证,算通过验证。
- @ScriptAssert(lang= ,script=, alias=)
- @URL(protocol=,host=, port=,regexp=, flags=)
多环境切换
profile是Spring对不同环境提供不同配置功能的支持,可以通过激活不同的环境版本,实现快速切换环境
- 方式一:多配置文件
- 方式二:yaml的多文档块(默认为8081端口)
配置文件加载位置
SpringBoot启动会扫描以下位置的application.properties 或者application.yml 文件作为SpringBoot的默认配置文件
- 优先级1:项目路径下的config文件夹配置文件
- 优先级2:项目路径下配置文件
- 优先级3:资源路径下的config文件夹配置文件
- 优先级4:资源路径下配置文件
优先级由高到低,高优先级的配置会覆盖低优先级的配置;
SpringBoot会从这四个位置全部加载主配置文件,互补配置;我们在最低级的配置文件中设置一个项目访问路径的配置来测试互补问题
server.servlet.context-path=/huake
扩展:指定位置加载配置文件
- 我们还可以通过spring.config.location来改变默认的配置文件位置
- 项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置
- 这种情况,一般是后期运维做的多,相同配置,外部指定的配置文件优先级最高
java -jar spring-boot-config.jar --spring.config.location=F://application.properties
外部加载配置文件的方式十分多,我们选择最常用的即可,在开发的资源文件中进行配置
自动配置原理再理解
-
表示这是一个配置类 @Configuration(proxyBeanMethods = false)
-
自动配置属性:HttpProperties @EnableConfigurationProperties(HttpProperties.class)
-
Spring的底层注解:根据不同的条件,来判断当前配置或者类是否生效 @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
-
在配置文件中能配置的东西,都存在一个固有的规律:xxxProperties 、xxxAutoConfiguration -
xxxAutoConfiguration 有默认值(而这些默认值的改变是通过xxxProperties 和配置文件的绑定),所以我们可以使用自定义的配置了
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer
# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener
# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration
# Failure analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.autoconfigure.data.redis.RedisUrlSyntaxFailureAnalyzer,\
org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\
org.springframework.boot.autoconfigure.flyway.FlywayMigrationScriptMissingFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer,\
org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryBeanCreationFailureAnalyzer,\
org.springframework.boot.autoconfigure.session.NonUniqueSessionRepositoryFailureAnalyzer
# Template availability providers
org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider
每一个这样的xxxAutoConfiguration 类都是容器中的一个组件,最后都加入到容器中;用他们来做自动配置
每一个自动配置类可以进行自动配置功能;
一句话总结:根据当前不同的条件判断,决定这个配置类是否生效!
一但这个配置类生效;这个配置类就会给容器中添加各种组件;这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
所有在配置文件中能配置的属性都是在xxxProperties 类中封装着;配置文件能配置什么就可以参照某个功能对应的这个属性类
自动装配的原理:
- SpringBoot启动会加载大量的自动配置类
- 我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中
- 我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)
- 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可
- xxxxAutoConfiguration:自动配置类(给容器中添加组件)
- xxxxProperties:封装配置文件中相关属性
@Conditional
- 了解完自动装配的原理后,我们来关注一个细节问题,自动配置类必须在一定的条件下才能生效;@Conditional派生注解(Spring注解版原生的@Conditional作用)
- 作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置里面的所有内容才生效;
那么多的自动配置类,必须在一定的条件下才能生效;也就是说,我们加载了这么多的配置类,但不是所有的都生效了
我们可以通过启用 debug=true 属性(默认为false);来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效
debug=true
- Postive matches:(自动配置类启用的:正匹配)
- Negative matches:(没有启动,没有匹配成功的自动配置类:负匹配)
- Unconditional classes:(没有条件的类)
输出的日志我们可以在这里看下:
SpringBoot Web开发
jar:webapp!
SpringBoot到底帮我们配置了什么?我们能不能进行修改?能修改哪些东西?能不能扩展?
- xxxxAutoConfiguration:向容器中自动配置组件
- xxxxProperties:自动配置类,装配配置文件中自定义的一些内容!
要解决的问题:
- 导入静态资源
- 首页
- jsp,模板引擎 Thymeleaf
- 装配扩展SpringMVC
- 增删改查
- 拦截器
- 国际化
静态资源
webjars
我们任意添加一个jsquery包 依此类推,优先级:resources > static(默认)> public
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
"classpath:/resources/", "classpath:/static/", "classpath:/public/" };
总结:
- 1、在SpringBoot,我们可以使用以下方式处理静态资源
- webjars(
localhost:8080/webjars ) - public、static、/**、resources
- 2、优先级:resources > static(默认)> public
模板引擎
前端交给我们的页面,是HTML页面,如果是我们以前开发,我们需要把他们转成JSP页面,JSP好处就是当我们查出一些数据转发到JSP页面以后,我们可以用jsp轻松实现数据的显示,及交互等。jsp支持非常强大的功能,包括能写Java代码,但是呢,
- 第一:我们现在的这种情况,SpringBoot这个项目首先是以jar的方式,不是war
- 第二:我们用的还是嵌入式的Tomcat,所以呢,他现在默认是不支持jsp的
那不支持jsp,如果我们直接用纯静态页面的方式,那给我们开发会带来非常大的麻烦,那怎么办呢,SpringBoot推荐你可以来使用模板引擎——Thymeleaf 。类似的模板引擎有jsp 、freemarker 等等,那如何去使用?
第一步:引入Thymeleaf,对于SpringBoot来说,什么事情不都是一个start的事情嘛,我们在去项目中引入一下。
- 1、Thymeleaf官网:
https://www.thymeleaf.org/ - 2、Thymeleaf在Github的主页:
https://github.com/thymeleaf/thymeleaf - 3、Spring官方文档:
https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/htmlsingle/#using-boot-starter ,找到我们对应的版本
<!-- Thymeleaf 我们都是基于3.x开发的-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
结论:只要需要使用thymeleaf,只需要导入对应的依赖就可以了!我们将html放在我们的templates即可
Thymeleaf语法
order | Feature | Attributes |
---|
1 | Fragment inclusion | th:insert & th:replace | 2 | Fragment iteration | th:each | 3 | Conditional evaluation | th:if & th:unless & th:switch & th:case | 4 | Local variable definition | th:object & th:with | 5 | General attribute modification | th:attr & th:attrprepend & th:attrappend | 6 | Specific attribute modification | th:value & th:href & th:src & … | 7 | Text(tag body modification) | th:text & th:utext | 8 | Fragment specificaiton | th:fragment | 9 | Fragment removal | th:remove |
演示一个小案例:(大致和JSP相似)
package com.blb.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Arrays;
@Controller
public class IndexController {
@RequestMapping("/test")
public String test(Model model){
model.addAttribute("msg", "<h1>hello SpringBoot</h1>");
model.addAttribute("users", Arrays.asList("huake", "wuli"));
return "test";
}
}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>This is Thymeleaf</title>
</head>
<body>
<div th:text="${msg}"></div>
<div th:utext="${msg}"></div>
<hr>
<h3 th:each="user:${users}" th:text="${user}"></h3>
<h3 th:each="user:${users}">[[ ${user} ]]</h3>
</body>
</html>
SpringMVC自动配置
在进行测试前,我们还需要知道一个东西,就是SpringBoot对我们的SpringMVC还做了哪些配置,包括如何扩展,如何定制。
地址:https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/boot-features-developing-web-applications.html
修改SpringBoot的默认配置
- 方式一:
- 这么多的配置,原理都是一样的,SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(如果用户自己配置@bean),如果有就用用户配置的,如果没有就用自动配置的;如果有些组件可以存在多个,比如我们的视图解析器,就将用户配置的和自己默认的组合起来!
|