Spring与springBoot
- Spring能做什么?
- 微服务应用
- 非阻塞式的响应式web应用
- 可运行在任何的云环境
- 无服务器应用
- 事件驱动,事实处理数据流
- 任务自动化批处理
- Spring的生态覆盖
- web开发
- 数据访问
- 安全控制
- 分布式应用
- 消息服务
- 移动开发
- 批处理
- ……
- Spring5重大升级特性
- 响应式编程
- 基于Java8的新特性,如接口默认实现等
- 重新设计了源码的结构
- 为什么用SpringBoot?
- 能快速创建出生产级别的Spring应用
- 是整合Spring技术栈的一站式框架
- 也是简化Spring技术栈的快速开发脚手架
- SpringBoot优点
- 可快速创建独立Spring应用
- 内嵌web服务器(Tomcat、Jetty、Undertow)
- 自动starter依赖,简化构建依赖关系及版本配置
- 自动配置Spring生态以及第三方框架功能
- 提供生产级别的监控、健康检查及外部化配置
- 无代码生成、无需编写XML
- SpringBoot缺点
- 版本迭代快,经常需关注其变化(即使缺点也是优点)
- 封装深,内部原理复杂,不宜精通
- 搞懂底层需对Spring框架有深入了解
当下技术背景
微服务成主流
- 微服务是一种架构风格
- 一个应用拆分为一组小型服务
- 每个服务运行在自己的进程内,也就是可独立部署和升级
- 服务之间使用轻量级HTTP交互
- 服务围绕业务功能拆分
- 可以由全自动部署机制独立部署
- 去中心化,服务自治。服务可以使用不同的语言、不同的存储技术
分布式系统的困难
- 远程调用
- 服务发现
- 负载均衡
- 服务容错
- 配置管理
- 服务监控
- 链路追踪
- 日志管理
- 任务调度
- ......
解决方案
Springboot + Spring Cloud
构建云原生应用
- 上云的困难
- 服务自愈
- 弹性伸缩
- 服务隔离
- 自动化部署
- 灰度发布
- 流量治理
- ......
- 主要与系统运维息息相关
- 了解云原生应用的特点
- 深入Docker容器化技术
- 掌握容器编排K8S核心技术
- 熟悉devops企业级CI/CD技术
- 了解新一代架构:Service Mesh 与 Serverless
如何学习SpringBoot?
入门
环境要求
- JDK8.0+
- Maven3.3+
- IDEA 2019.1.2+
编码
- 配置Maven settings.xml,配置镜像加速与编译的JDK版本
- 创建Maven工程,引入依赖
- 创建主程序(主启动类)
- 创建HelloWorld Controller
- 运行main方法,测试
- 配置springboot插件,打可执行包
- 创建application.properties,配置端口
- 注意事项:
- jar包要等他们下完
- 取消掉cmd的快速编辑模式
自动配置原理
Springboot特点
1. 依赖管理
<!-- 依赖管理 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
<!-- 他的父项目 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
- 几乎声明了所有开发中常用的依赖的版本号
- 这就是自动版本仲裁机制
1、引入依赖默认都可以不写版本 2、引入非版本仲裁的jar,要写版本号
- 修改默认版本号
<!--
1、可以查看spring-boot-dependencies里面规定当前依赖的版本用的 key。
2、在当前项目里面可以重写配置的key,如MySQL:
-->
<properties>
<mysql.version>5.1.43</mysql.version>
</properties>
- 导入starter场景启动器:
<!--
1、见到很多 spring-boot-starter-* : *就某种场景
2、只要引入starter,这个场景的所有常规需要的依赖都将自动引入
3、SpringBoot所有支持的场景见下方starter链接
4、见到的 *-spring-boot-starter是第三方为我们提供的简化开发的场景启动器,这也是springboot官方推荐的命名规范。
5、所有场景启动器最底层的依赖:
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starters</artifactId>
<version>2.3.4.RELEASE</version>
<scope>compile</scope>
</dependency>
2. 自动配置
- 比如Tomcat,内置Tomcat依赖,内部已默认各种配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.3.4.RELEASE</version>
<scope>compile</scope>
</dependency>
- 再比如SpringMVC
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- 自动引入SpringMVC全套组件
- 自动配好SpringMVC常用组件(功能)
- 如:字符编码问题,文件上传大小限制、扫描路径等等
- 默认扫描路径:主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
- 无需以前的包扫描配置
- 想改变扫描路径:
- @SpringBootApplication(scanBasePackages="com.qinchen")
- 或者@ComponentScan 指定扫描路径
- 留意:
@SpringBootApplication
// 等同于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.atguigu.boot")
- 各种配置拥有默认值,最终都是映射到某个类上,如:MultipartProperties
- 这个类会在容器中创建对象
- 所有starter,会按需加载自动配置项
- 引入了哪些场景这个场景的自动配置才会开启
- SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面
- 查看所有内置配置参数
3. @Conditional 条件装配器
- 条件装配:满足Conditional指定的条件,则进行组件注入
- @ImportResource
- 导入原生配置文件
============beans.xml=============
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="haha" class="com.atguigu.boot.bean.User">
<property name="name" value="zhangsan"></property>
<property name="age" value="18"></property>
</bean>
<bean id="hehe" class="com.atguigu.boot.bean.Pet">
<property name="name" value="tomcat"></property>
</bean>
</beans>
@ImportResource("classpath:beans.xml")
public class MyConfig {}
boolean haha = run.containsBean("haha");
boolean hehe = run.containsBean("hehe");
System.out.println("haha:"+haha);//true
System.out.println("hehe:"+hehe);//true
@ConfigurationProperties
- 配置绑定
/**
* 只有在容器中的组件,才会拥有SpringBoot提供的强大功能
*/
@Component
@ConfigurationProperties(prefix = "mycar")
public class Car {
}
- 或者使用:@EnableConfigurationProperties + @ConfigurationProperties
原理关键注解
@SpringBootApplication // 主启动类的注解,是下面几个注解的组合注解
@SpringBootConfiguration // 最终还是一个Configuration
@EnableAutoConfiguration // 这是研究重点
@ComponentScan // 制定扫描范围
@Configuration // 配置类
@AutoConfigurationPackage // 自动配置包规则,指定了默认包规则
// 核心关键
@Import(AutoConfigurationImportSelector.class) // 给容器中批量导入一些组件
- 127个场景自动配置,然后按照条件装配规则,按需加载
// 来自读取以下文件
Enumeration<URL> urls = classLoader != null ?
classLoader.getResources("META-INF/spring.factories") :
ClassLoader.getSystemResources("META-INF/spring.factories");
spring-boot-autoconfigure\2.3.4.RELEASE\spring-boot-autoconfigure-2.3.4.RELEASE.jar!\META-INF\spring.factories
例如AspectJAutoProxyingConfiguration,默认就不会加载,不可用
/**
* 思考:这是什么意思?
* 文件上传解析器,容器中有MultipartResolver bean
* 但容器中没有名字为 MULTIPART_RESOLVER_BEAN_NAME 组件
* @Bean标注的方法传入了对象参数,这个参数的值就会从容器中找
* 目的:防止有些用户配置的文件上传解析器名称未规范起
*/
@Bean
@ConditionalOnBean(MultipartResolver.class)
@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
public MultipartResolver multipartResolver(MultipartResolver resolver) {
// Detect if the user has created a MultipartResolver but named it incorrectly
return resolver;
}
/** 用户自己配置了以用户优先,用户没配置,加载下面内置bean */
@Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(Encoding.Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(Encoding.Type.RESPONSE));
return filter;
}
总结
- SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
- 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值xxxxProperties里面拿
- xxxProperties和配置文件进行了绑定
- 生效的配置类就会给容器中装配很多组件
- 只要容器中有这些组件,相当于这些功能就有了
- 定制化配置
- 用户直接自己@Bean替换底层的组件
- 用户去看这个组件是获取的配置文件什么值就去修改。
- xxxxxAutoConfiguration ---> 组件 ---> xxxxProperties里面拿值 ----> application.properties
- 具体想看哪些配置类生效,可以配置
debug=true
查看日志
Springboot 开发小技巧
- Lombok ,简化JavaBean开发,简化日志打印
- dev-tools,简单工程可使用,大型项目不好用
- 实则为自动重启工具
- 真正热加载,考虑使用Jrebel
- Spring Initailizr,项目初始化引导,自动创建项目结构