spring boot2.0深度实践
第一部分,简单入门

从图中可以看出,Spring Framework是最低层的应用,其次是Spring Boot,最后是Spring Cloud。
Spring Framework是一种java EE的框架。
Spring Boot是一种快速构建的spring 应用。
Spring Cloud是构建Spring boot的一种分布式的应用环境。
spring boot 2.0的新特性

支持jdk1.8和Kotlin是因为它依赖的底层Spring Framework的变更,Spring Framework5.0及以上版本。
WEB Flux是新型编程模型,他对spring mvc编程模型作出了补充。主要提出了声明式函数式编程。




开启自己的第一个spring boot实验项目
需要访问spring官网start.spring.io,使用官方在线构建工具来构建基础的应用包。

如图,选择我们要的特性,就可以生成代码,下载下来了


这里引入的就是webflux的相关jar包

我们再启动入口,进行run或者debug都可以启动


web容器是Netty,默认端口是8080,进程号是14856

第二阶段我们实现web Flux

查看web flux的帮助文档。
https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux

- 回顾之前:Servlet
- 请求接口:ServletRequest 或者HttpServletRequest
- 响应接口:ServletResponse或者HttpServletResponse
- spring 5.0以后,重新定义了请求和响应接口
- 请求接口:ServerRequest
- 响应接口:ServerResponse
-
这样重新定义的好处在于,既可以支持基于http协议的Servlet规范,也可以支持自定义,比如Netty(Web Server)
image.png
- Flux是0-N个对象集合
- Mono是0-1个对象集合
- 因为Reactive中的Flux或Mono是异步处理(非阻塞的)。之前的集合对象几乎都是同步处理(阻塞的)
-
Flux或者Mono都是Publisher
相当于我通过代码直接可以把rest入口注册到容器中。
image.png

有同学会有疑问,为什么用这种方式来生命rest入口呢?
答案:因为他是利用Recative中的Flux和Mono异步处理非阻塞特点。来提高吞吐量,而以前的方式是同步处理的吞吐量有瓶颈
下面我们讲多模块spring boot项目

第一步把我们的单一工程改成父级工程,把packaging标签中的值由jar变成pom

第二部,创建父级项目的子模块

对应目录文件,进行搬迁,直接拖拽即可,拖拽完成后,直接删除父级工程下的相应文件即可。


最终执行jar文件命令:java -jar xxxx.jar
第二部分,深度进阶







其中EnableAutoConfiguration注解就是自动装配的配置,其实我们SpringBootApplication的注解当中就包含了EnableAutoConfiguration注解。



生产准备特性概括可以说是监控工具类的非功能化特性,比如metrics是主要对cpu,磁盘、内存等资源利用率。
configprops是可以通过endpoint来调整应用的行为。外部化配置在spring boot工程中应用非常广泛,他是来自于spring framework,只是在spring boot中做了概念变更。

传统的web应用在spring boot的应用
Servlet:实现步骤
1、实现:@WebServlet 默认是同步模式, 继承HttpServlet
2、注册:@ServletComponentScan
@ServletComponentScan(basePackages = "com.ls.demo.servlet")

3、映射:URL映射
@WebServlet(urlPatterns = "/my/servlet")

webservlet异步非阻塞
如果要实现异步非阻塞servlet,我们需要对上面的@WebServlet做调整


@WebServlet(urlPatterns = "/my/servlet",asyncSupported = true)
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
AsyncContext asyncContext=req.startAsync();
asyncContext.start(()->{
try {
resp.getWriter().println("hello man");
//触发完成,否则响应一直不会结束,否则会超时报错,
asyncContext.complete();
} catch (IOException e) {
e.printStackTrace();
}
});
}
Spring Mvc:实现步骤


Web flux核心:
Web mvc注解兼容:@Controller @RequestMapping @ResponseBody @RequestBody
函数式声明:
RouterFunction
异步非阻塞:
Servlet 3.1+
Netty Reactory
应用场景:试图应用,Rest应用
性能测试:web flux的性能到底如何?



传统web容器和webflux容器是没办法共存的。
自定义Servlet Web Server
要实现自定义要首先了解一个WebServerFactoryCustomizer接口,这个接口是spring boot2.0新加入的一个接口。在spring boot1.0中,这个接口是不存在的,这是个总接口,它既包含tomcat实现,也包含netty实现,大家按需取用即可。




自定义Reactive Web Server
要实现自定义要首先了解一个ReactiveWebServerFactoryCustomizer接口,这个接口其实也同样集成了WebServerFactoryCustomizer接口,也就是说传统的web server的特性他也加以传承了。

如果我们要对spring boot的容器进行自定义实现就看可以对他进行重写和升级,都是可以无缝对接的。
数据相关
数据操作我们主要关心的是关系型数据库
JDBC:数据源、JdbcTemplate、自动装配(spring boot默认是不支持多数据源的,要想支持必须需要特殊操作。)
JPA:(java持久层api)实体映射关系、实体操作、自动装配
事务:Spring 事务抽象、JDBC事务处理、自动装配。

JDBC在Boot中的使用
添加jdbc依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

我们在添加入jdbc依赖后,回自动加载了一个性能非常好的HikariCP数据库连接池,这是在spring 2.0当中新加入的连接池。
数据源
javax.sql.DataSource
org.springframework.jdbc.core.JdbcTemplate

自动装配:
JdbcTemplateAutoConfiguration,他也是被@EnableAutoConfiguration的装配注解包含的。

JPA:
主要依赖是
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
实体映射关系:
@javax.persistence.OneToOne
@javax.persistence.OneToMany
@javax.persistence.ManyToOne
@javax.persistence.ManyToMany
实体操作:
javax.persistence.EntityManager
这是个接口,里面有CRUD的操作方法

自动装配
JPA他同样在boot中支持自动装配

事务(Transaction)
事务的依赖有些特殊,如果boot中想使用事务需要依赖springframework的包
依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
TransactionManager是一个跟接口,他有两个重要的事务实现类
PlatformTransactionManager
ReactiveTransactionManager

spring的事务处理:
首先看下PlatformTransactionManager
看源码:
JtaTransactionManager

jdbc的事务处理:
DataSourceTransactionManager
自动装配:

功能扩展

Spring Application
失败分析:FailureAnalysisReporter这个接口是spring boot1.4才能使用

应用特性:
SpringApplication里面可以使用很多Fluent API

Spring boot 外部化配置
https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/appendix-application-properties.html
外部化配置在spring boot2.0做了很大调整,spring boot1.0是使用的配置属性PropertySources来操作的,而spring boot2.0它改成了ConfigurationProperty来进行操作,我们可以看下它的源码实现

ConfigurationProperty里面除了有普通的key和value属性外,还新增了一种属性,叫origin,这是属性是配置的来源,这个是用来解决什么问题呢?他是用来方便你跟踪配置源的。
@Profile:是条件注解,比如你服务器应用加载参数,区分生产环境和测试环境,就用用它来做区分。在spring 4之前都是用它,之后就用@Conditional来代替
@PropertySources:配置属性在spring中有两种实现方式,一种是注解方式,一种是接口方式。

运维管理(Spring boot Actuator)
前面我介绍的都是些spring boot的一些功能性的开发。我们从这里开始就是些运维类的介绍。

端点(EndPoints)
Web EndPoints
JMX EndPoints
要想使用就要添加相应的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Web EndPoints
这时候我们再去启动,控制台会有很多额外的信息

你把http://localhost:8080/actuator放入到浏览器中就能得到很多信息

http://localhost:8080/actuator/health这个地址也会返回健康信息,

JMX EndPoints
另外一种方式也可以看到更全面你的资源监控信息jconsole,他是jdk的bin目录中的一个自带的工具,可以看到进程的资源使用情况。


明显比Web EndPoints的信息要多很多,其实我们也是可以配置Web EndPoints的展示信息的。
我们在web层组件中找到application.properties中添加
management.endpoints.web.exposure.include=*
放开所有endpoints,看下图明显多了很多

如果我们要关闭,那就需要在application.properties中添加
management.endpoints.web.exposure.exclude=*
如果想了解关于spring boot的更多特性,请仔细查看官网,查看文档时一定要对应你的版本例如:https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/index.html
另外一个知识点
metrics信息:

这个链接里面会告诉我们很多信息
{"names":["http.server.requests",
"jvm.buffer.count",
"jvm.buffer.memory.used",
"jvm.buffer.total.capacity",
"jvm.classes.loaded",
"jvm.classes.unloaded",
"jvm.gc.live.data.size",
"jvm.gc.max.data.size",
"jvm.gc.memory.allocated",
"jvm.gc.memory.promoted",
"jvm.gc.pause",
"jvm.memory.committed",
"jvm.memory.max",
"jvm.memory.used",
"jvm.threads.daemon",
"jvm.threads.live",
"jvm.threads.peak",
"jvm.threads.states",
"logback.events",
"process.cpu.usage",
"process.start.time",
"process.uptime",
"system.cpu.count",
"system.cpu.usage"]
}
这里的属性是可以复制在浏览器里进行查看对应的值的。
例如:http://localhost:8080/actuator/metrics/jvm.memory.used
