小工具知识网

当前位置: 首页 > 行业知识 > 一文弄懂 SpringBoot3 新特性

行业知识

一文弄懂 SpringBoot3 新特性

2026-11-10 19:56:52 来源:互联网转载

本文参考自:

【尚硅谷SpringBoot零基础教程,面试&加薪必会springboot3】 https://www.bilibili.com/video/BV1Es4y1q7Bf/?p=88&share_source=copy_web&vd_source=d45508e20b7e3eae6233a57ab7104d22

1.前置要求

1.环境要求

环境&工具版本(or later)
SpringBoot3.0.5+
IDEA2021.2.1+
Java17+
Maven3.5+
Tomcat10.0+
Servlet5.0+
GraalVM Community22.3+
Native Build Tools0.9.19+

2.SpringBoot是什么

SpringBoot 帮我们简单、快速地创建一个独立的、生产级别的 Spring 应用(说明:SpringBoot底层是Spring)

大多数 SpringBoot 应用只需要编写少量配置即可快速整合 Spring 平台以及第三方技术

特性

  • 快速创建独立Spring应用,无需像SSM一样,导一堆的包,写一堆配置
  • 直接嵌入Servlet容器,如Tomcat、Jetty等,无需部署 war 包,直接打包成jar包,java -jar执行
  • 重点: 提供了可选的场景启动器starter,简化应用整合,Spring Boot会自动管理这些依赖项的版本,确保它们之间的兼容性。
  • 重点: 按需自动配置Spring以及第三方库,约定大于配置,每个场景都有默认配置,需要自定义只需要在配置文件修改即可。
  • 提供生产级特性,如监控指标、健康检查、外部化配置等

    总结:简化开发,简化配置,简化整合,简化部署,简化监控,简化运维。

    2.改变&新特性

    1.自动配置包位置变化

    1. SpringBoot2.X

      META-INF/spring.factories

    2. SpringBoot3.X

      META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

    2.jakata api迁移

    1.SpringBoot2.X

    2.SpringBoot3.X

    3.SpringBoot3使用druid有问题,因为它引用的是旧的包

    该问题已经得到官方解决:

    解决SpringBoot3整合Druid的兼容性问题_druid-spring-boot-3-starter-CSDN博客

    方法:将依赖有原先的依赖

       com.alibaba   druid-spring-boot-starter   1.2.18

    改为

        com.alibaba    druid-spring-boot-3-starter    1.2.20

    3.新特性–Problemdetails

    SpringBoot3提供的一个新规范,当发生某些异常时,以RFC 7807规范方式返回错误数据

    原理

    1. 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();    }}
    2. 处理以下异常。如果系统出现以下异常,会被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拦截了

    4.新特性–函数式接口

    SpringMVC 5.2 以后 允许我们使用函数式的方式,定义Web的请求处理流程。

    函数式接口

    Web请求处理的方式:

    1. @Controller + @RequestMapping:耦合式 (路由、业务耦合)
    2. 函数式Web:分离式(路由、业务分离)

    核心类

    • RouterFunction - 定义路由信息。发什么请求,谁来处理
    • RequestPredicate - 定义请求规则:请求谓语。请求方式(GET、POST)、请求参数
    • ServerRequest - 封装请求完整数据
    • ServerResponse - 封装响应完整数据

      示例

      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号用户 */@Configurationpublic class WebFunctionConfig {    /**     * 函数式Web:     * 1、给容器中放一个Bean:类型是 RouterFunction,集中所有路由信息     * 2、每个业务准备一个自己的Handler     *     *     * 核心四大对象     * 1、RouterFunction: 定义路由信息。发什么请求,谁来处理     * 2、RequestPredicate:定义请求规则:请求谓语。请求方式(GET、POST)、请求参数     * 3、ServerRequest:  封装请求完整数据     * 4、ServerResponse: 封装响应完整数据     */    @Bean    public RouterFunction 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@Servicepublic 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 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();    }}

      5.支持GraalVM与AOT

      • AOT 提前编译:程序执行前,全部先编译成机器码

      • JIT 即使编译:程序边 编译,边运行

        JITAOT
        优点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应用程序的方式:

            1. 在HotSpot JVM上使用Graal即时(JIT)编译器
            1. 作为预先编译(AOT)的本机可执行文件运行(本地镜像)。

            GraalVM的多语言能力使得在单个应用程序中混合多种编程语言成为可能,同时消除了外部语言调用的成本。

            具体示例:7、AOT (yuque.com)

上一篇:头部导航与页脚固定设置全解析,实现网页布局稳固化!

下一篇:NICE41辅助怎么用?