赞
踩
本文参考自:
【尚硅谷SpringBoot零基础教程,面试&加薪必会springboot3】 https://www.bilibili.com/video/BV1Es4y1q7Bf/?p=88&share_source=copy_web&vd_source=d45508e20b7e3eae6233a57ab7104d22
环境&工具 | 版本(or later) |
---|---|
SpringBoot | 3.0.5+ |
IDEA | 2021.2.1+ |
Java | 17+ |
Maven | 3.5+ |
Tomcat | 10.0+ |
Servlet | 5.0+ |
GraalVM Community | 22.3+ |
Native Build Tools | 0.9.19+ |
SpringBoot 帮我们简单、快速地创建一个独立的、生产级别的 Spring 应用(说明:SpringBoot底层是Spring)
大多数 SpringBoot 应用只需要编写少量配置即可快速整合 Spring 平台以及第三方技术
特性
总结:简化开发,简化配置,简化整合,简化部署,简化监控,简化运维。
SpringBoot2.X
META-INF/spring.factories
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
1.SpringBoot2.X
2.SpringBoot3.X
3.SpringBoot3使用druid有问题,因为它引用的是旧的包
该问题已经得到官方解决:
解决SpringBoot3整合Druid的兼容性问题_druid-spring-boot-3-starter-CSDN博客
方法:将依赖有原先的依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.18</version>
</dependency>
改为
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.20</version>
</dependency>
SpringBoot3提供的一个新规范,当发生某些异常时,以RFC 7807
规范方式返回错误数据
原理
ProblemDetailsErrorHandlingConfiguration
是一个 @ControllerAdvice
集中处理系统异常
@Configuration(proxyBeanMethods = false)
//配置过一个属性 spring.mvc.problemdetails.enabled=true
@ConditionalOnProperty(prefix = "spring.mvc.problemdetails", name = "enabled", havingValue = "true")
static class ProblemDetailsErrorHandlingConfiguration {
@Bean
@ConditionalOnMissingBean(ResponseEntityExceptionHandler.class)
ProblemDetailsExceptionHandler problemDetailsExceptionHandler() {
return new ProblemDetailsExceptionHandler();
}
}
处理以下异常。如果系统出现以下异常,会被SpringBoot支持以 RFC 7807
规范方式返回错误数据
@ExceptionHandler({ HttpRequestMethodNotSupportedException.class, //请求方式不支持 HttpMediaTypeNotSupportedException.class, HttpMediaTypeNotAcceptableException.class, MissingPathVariableException.class, MissingServletRequestParameterException.class, MissingServletRequestPartException.class, ServletRequestBindingException.class, MethodArgumentNotValidException.class, NoHandlerFoundException.class, AsyncRequestTimeoutException.class, ErrorResponseException.class, ConversionNotSupportedException.class, TypeMismatchException.class, HttpMessageNotReadableException.class, HttpMessageNotWritableException.class, BindException.class })
效果
spring.mvc.problemdetails.enabled=true
开启后 会使用新的MediaType
Content-Type: application/problem+json+ 额外扩展返回
并且返回信息也会变化
例:写一个GET接口,用POST访问
原因:主要是因为该请求异常被 HttpRequestMethodNotSupportedException
拦截了
SpringMVC 5.2
以后 允许我们使用函数式的方式,定义Web的请求处理流程。函数式接口
Web请求处理的方式:
@Controller + @RequestMapping
:耦合式 (路由、业务耦合)- 函数式Web:分离式(路由、业务分离)
核心类
示例
package com.atguigu.web.config; import com.atguigu.web.bean.Person; import com.atguigu.web.biz.UserBizHandler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.web.servlet.function.RequestPredicates; import org.springframework.web.servlet.function.RouterFunction; import org.springframework.web.servlet.function.RouterFunctions; import org.springframework.web.servlet.function.ServerResponse; /** * @author lfy * @Description * @create 2023-04-18 21:46 */ /** * 场景:User RESTful - CRUD * ● GET /user/1 获取1号用户 * ● GET /users 获取所有用户 * ● POST /user 请求体携带JSON,新增一个用户 * ● PUT /user/1 请求体携带JSON,修改1号用户 * ● DELETE /user/1 删除1号用户 */ @Configuration public class WebFunctionConfig { /** * 函数式Web: * 1、给容器中放一个Bean:类型是 RouterFunction<ServerResponse>,集中所有路由信息 * 2、每个业务准备一个自己的Handler * * * 核心四大对象 * 1、RouterFunction: 定义路由信息。发什么请求,谁来处理 * 2、RequestPredicate:定义请求规则:请求谓语。请求方式(GET、POST)、请求参数 * 3、ServerRequest: 封装请求完整数据 * 4、ServerResponse: 封装响应完整数据 */ @Bean public RouterFunction<ServerResponse> userRoute(UserBizHandler userBizHandler/*这个会被自动注入进来*/){ return RouterFunctions.route() //开始定义路由信息 .GET("/user/{id}", RequestPredicates.accept(MediaType.ALL), userBizHandler::getUser) .GET("/users", userBizHandler::getUsers) .POST("/user", RequestPredicates.accept(MediaType.APPLICATION_JSON), userBizHandler::saveUser) .PUT("/user/{id}", RequestPredicates.accept(MediaType.APPLICATION_JSON), userBizHandler::updateUser) .DELETE("/user/{id}", userBizHandler::deleteUser) .build(); } }
package com.atguigu.web.biz; import com.atguigu.web.bean.Person; import jakarta.servlet.ServletException; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import org.springframework.web.servlet.function.ServerRequest; import org.springframework.web.servlet.function.ServerResponse; import java.io.IOException; import java.util.Arrays; import java.util.List; /** * @author lfy * @Description 专门处理User有关的业务 * @create 2023-04-18 21:55 */ @Slf4j @Service public class UserBizHandler { /** * 查询指定id的用户 * @param request * @return */ public ServerResponse getUser(ServerRequest request) throws Exception{ String id = request.pathVariable("id"); log.info("查询 【{}】 用户信息,数据库正在检索",id); //业务处理 Person person = new Person(1L,"哈哈","aa@qq.com",18,"admin"); //构造响应 return ServerResponse .ok() .body(person); } /** * 获取所有用户 * @param request * @return * @throws Exception */ public ServerResponse getUsers(ServerRequest request) throws Exception{ log.info("查询所有用户信息完成"); //业务处理 List<Person> list = Arrays.asList(new Person(1L, "哈哈", "aa@qq.com", 18, "admin"), new Person(2L, "哈哈2", "aa2@qq.com", 12, "admin2")); //构造响应 return ServerResponse .ok() .body(list); //凡是body中的对象,就是以前@ResponseBody原理。利用HttpMessageConverter 写出为json } /** * 保存用户 * @param request * @return */ public ServerResponse saveUser(ServerRequest request) throws ServletException, IOException { //提取请求体 Person body = request.body(Person.class); log.info("保存用户信息:{}",body); return ServerResponse.ok().build(); } /** * 更新用户 * @param request * @return */ public ServerResponse updateUser(ServerRequest request) throws ServletException, IOException { Person body = request.body(Person.class); log.info("保存用户信息更新: {}",body); return ServerResponse.ok().build(); } /** * 删除用户 * @param request * @return */ public ServerResponse deleteUser(ServerRequest request) { String id = request.pathVariable("id"); log.info("删除【{}】用户信息",id); return ServerResponse.ok().build(); } }
AOT 提前编译:程序执行前,全部先编译成机器码
JIT 即使编译:程序边 编译,边运行
JIT | AOT | |
---|---|---|
优点 | 1.具备实时调整能力 2.生成最优机器指令 3.根据代码运行情况优化内存占用 | 1.速度快,优化了运行时编译时间和内存消耗 2.程序初期就能达最高性能 3.加快程序启动速度 |
缺点 | 1.运行期边编译速度慢 2.初始编译不能达到最高性能 | 1.运行期边编译速度慢 2.初始编译不能达到最高性能 |
语言
编译型语言:需要编译器 C C++
解释型语言:需要解释器 Python、js、PHP
半编译半解释型语言:既有编译器有有解释器 JAVA
GraalVM
GraalVM是一个高性能的JDK,旨在加速用Java和其他JVM语言编写的应用程序的执行,同时还提供JavaScript、Python和许多其他流行语言的运行时。
GraalVM提供了两种运行Java应用程序的方式:
- 在HotSpot JVM上使用Graal即时(JIT)编译器
- 作为预先编译(AOT)的本机可执行文件运行(本地镜像)。
GraalVM的多语言能力使得在单个应用程序中混合多种编程语言成为可能,同时消除了外部语言调用的成本。
具体示例:7、AOT (yuque.com)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。