首页 > 其他分享 >Spring Boot 3.0 升级 实战踩坑记录

Spring Boot 3.0 升级 实战踩坑记录

时间:2023-12-24 16:55:25浏览次数:40  
标签:Java 3.0 Spring Boot 升级 版本

转载自:https://juejin.cn/post/7176204472082038840

Spring Boot 3.0 升级 实战踩坑记录

 

Spring Boot常用于Java后端开发,于2022年11月24日正式发布了3.0.0版本,带来了全新的特性、升级了依赖版本乃至Java版本,与此同时也弃用或更改了一些旧版本中的写法,导致了需要修改代码或配置文件。
笔者尝鲜去升级了一下Spring Boot 3.0,本篇文章将会简要归纳总结一下笔者在升级的时候需要进行的操作、遇到的问题和解决方案,希望能对各位读者有所帮助。

版本信息

作为参考,笔者升级后各版本信息如下:

  • Spring Boot 3.0.0
  • Spring 6.0.2
  • Spring Security 6.0.0
  • Spring Data JPA 3.0.0
  • Java 17
  • Gradle 7.6

确认依赖

Spring框架的版本可以通过Gradle插件io.spring.dependency-management来进行自动管理,升级Spring Boot版本时会带着Spring框架以及Spring生态全家桶一起升级。
推荐安装依赖Spring Boot Properties Migrator来检查是否有被弃用的Spring Boot配置文件属性,可以在build.gradle文件里的dependencies闭包中添加:

  gradle 复制代码
implementation 'org.springframework.boot:spring-boot-properties-migrator'

在升级完成后,可以移除这个依赖。

升级MySQL JDBC驱动(可选)

这一步不是必须的,MySQL的JDBC驱动在2022年10月份的时候更改过名称,虽然不改也能继续用,不过还是建议顺路一起改一下吧,在build.gradle文件中的dependencies,将mysql:mysql-connector-java更改为com.mysql:mysql-connector-j,例如:

  gradle 复制代码
runtimeOnly 'com.mysql:mysql-connector-j'

升级到2.7

为了确保升级顺利,不要急着一步到位直接升级3.0,建议先将Spring Boot升级到2.7版本确认2.x时代的兼容性,截止发稿时最新的版本为2.7.6,可以将build.gradle中的plugins闭包内的org.springframework.boot版本改为2.7.6,例如:

  gradle 复制代码
plugins {
	id 'org.springframework.boot' version '2.7.6'
	id 'io.spring.dependency-management' version '1.1.0'
	id 'java'
}

构建并启动服务端确认没有问题后,可以关闭服务端,进行下一步升级。

升级Java版本

从Spring Boot 3.0开始,最低支持的Java版本变为Java 17、最高支持Java 19,如果还在使用Java 8或者Java 11的话,首先需要升级Java。
推荐使用LTS版本的Java 17,Oracle官方的JDK可以在这里下载,也可以使用诸如Eclipse Temurin之类的第三方构建OpenJDK,还可以使用Docker镜像openjdk:17.0.2。如果使用的是IntelliJ IDEA,可以在文件-项目结构-平台设置-SDK中点击+自动下载JDK,下载完毕后在项目设置-项目中更换SDK语言级别
如果对自己的代码能否在高版本Java正常运行没有信心,可以使用Eclipse Migration Toolkit for Java(EMT4J) 之类的工具检查一下是否存在不兼容高版本的写法。

升级Gradle版本

高版本的Java也需要高版本的Gradle进行构建,为了成功构建,还需要升级Gradle版本,对应的最低支持版本如下:

JavaGradle
17 7.3
18 7.5
19 7.6

例如,上一步安装了Java 17,这一步可以选择Gradle 7.3.3、7.4.2、7.5.1、7.6等版本,如果没有特殊需求的话,建议一步到位选择最新版本(可以在发布页面找到),截至发稿时的最新版本为7.6。
如果使用的是Gradle Wrapper,可以直接修改gradle/wrapper/gradle-wrapper.properties中的distributionUrl,例如:

  properties 复制代码
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip

升级完毕后,使用Java 17或Java 19构建并启动Spring Boot 2.7的服务端,如果没有问题可以关闭后进行下一步。

升级到3.0

与升级到2.7类似,修改build.gradle中的插件版本即可,截止发稿时最新的版本为3.0.0(最新版本可以在发布页面找到),例如:

  gradle 复制代码
plugins {
	id 'org.springframework.boot' version '3.0.0'
	id 'io.spring.dependency-management' version '1.1.0'
	id 'java'
}

迁移到Jakarta EE

从Spring Boot 3.0开始,原有的Java EE被彻底弃用,换用Jakarta EE,也就是说,所有包名为javax.*的引用都需要更换为jakarta.*。如果使用的是IntelliJ IDEA,可以点击重构-迁移软件包和类-Java EE to Jakarta EE来自动完成扫描和迁移。
此时可以尝试构建并启动服务端,如果能成功启动,恭喜Spring Boot 3.0升级成功。如果无法正常构建或启动,还需要继续阅读问题排查。

构建问题排查

以下是笔者遇到的一些会导致通不过构建的问题。

gRPC

找不到javax.annotation.Generated

如果使用了gRPC,会根据proto文件生成一些Java文件,生成的Java文件中会有@javax.annotation.Generated注解,而上文提到了Spring Boot 3.0已经全面换成Jakarta EE,如果还需要使用Java EE的类,必须得自己手动引入依赖。
依赖引入到build.gradle文件中的dependencies,需要添加:

  gradle 复制代码
implementation 'javax.annotation:javax.annotation-api:1.3.2'

Spring Security

Spring Security 6.0也是一个大升级,光这部分又能单独写一篇文章,本文简单讲一下最关键的变更。

找不到类org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter

几乎是大家都会用去的WebSecurityConfigurerAdapter被删除了,原先继承这个的类现在无需继承任何类,只需要带上@Configuration注解。
原本配置WebSecurityHttpSecurityconfigure方法变为普通的@Bean方法,分别返回WebSecurityCustomizerSecurityFilterChain
原先的方法authorizeRequests变为authorizeHttpRequests、方法antMatchers变为requestMatchers
修改自Spring Security官方博客的例子:

  java 复制代码
// 以前的写法
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers("/ignore1", "/ignore2");
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .httpBasic(withDefaults());
    }
}
  java 复制代码
// 现在的写法
@Configuration
// 不再继承于WebSecurityConfigurerAdapter
public class SecurityConfiguration {
    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        // WebSecurityCustomizer是一个类似于Consumer<WebSecurity>的接口,函数接受一个WebSecurity类型的变量,无返回值
        // 此处使用lambda实现WebSecurityCustomizer接口,web变量的类型WebSecurity,箭头后面可以对其进行操作
        // 使用requestMatchers()代替antMatchers()
        return (web) -> web.ignoring().requestMatchers("/ignore1", "/ignore2");
    }
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            //使用authorizeHttpRequests()代替authorizeRequests()
            .authorizeHttpRequests((authz) -> authz
                //这种写法被称为Lambda DSL,代替原来的and()链式操作
                .anyRequest().authenticated()
            )
            .httpBasic(withDefaults());
        // 需要进行build(),返回SecurityFilterChain
        return http.build();
    }
}

运行问题排查

以下是笔者遇到的一些会导致无法启动服务端的问题。

Spring Data JPA

找不到类org.hibernate.dialect.MySQL5InnoDBDialect

一般用于spring.jpa.properties.hibernate.dialect,如果使用的是MySQL,请将其更改为org.hibernate.dialect.MySQLDialect,例如:

  properties 复制代码
org.hibernate.dialect.MySQL5InnoDBDialect=org.hibernate.dialect.MySQLDialect

找不到类org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy

一般用于spring.jpa.hibernate.naming.physical-strategy,如果需要将驼峰转换为下划线,请其将更改为org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy,例如:

  properties 复制代码
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy

参考链接

标签:Java,3.0,Spring,Boot,升级,版本
From: https://www.cnblogs.com/wanghengbin/p/17924590.html

相关文章

  • 初识SpringCloud
    一、SpringCloudSpringCloud是目前国内使用最广泛的微服务框架。官网地址:https://spring.io/projects/spring-cloud/SpringCloud集成了各种微服务功能组件,并基于SpringBoot实现了这些组件的自动装配,从而提供了良好的开箱即用体验:服务注册发现:Eureka、Nacos、Consul服务远程调用:Ope......
  • Spring框架的认证与授权 - Spring Security
    引言在构建应用程序时,确保数据安全和用户身份验证是至关重要的。SpringSecurity为这些安全需求提供了全面的解决方案。SpringSecurity的基本概念SpringSecurity提供了一系列的认证和授权策略来保护应用程序。它支持多种认证机制,包括表单登录、OAuth、LDAP等,并允许细粒度的权限控......
  • SpringCloudAlibaba商城
    功能预览用户端登录界面注册界面网站介绍保健品保健品详情养生知识养生知识详情文章中心文章详情--用户关注个人中心我的购物车我的订单我的养生知识文章管理文章发布/编辑  支付宝沙箱保健品结算保健品支付界面保健品支付成功界面支......
  • Spring Bean的生命周期
    在Spring框架中,在IOC容器中管理的Bean分为单例和原型两种,单例Bean在容器启动时就实例化,原型Bean则是每次从容器中请求时才会实例化。而不管是单例还是原型,Bean的生命周期都是基本一致的。生命周期流程图SpringBean的生命周期分为四个阶段:实例化Instantiation-->属性赋值Pop......
  • spring加载bean流程解析
    spring加载bean流程解析转载自:https://www.cnblogs.com/wyq178/p/11415877.htmlspring作为目前我们开发的基础框架,每天的开发工作基本和他形影不离,作为管理bean的最经典、优秀的框架,它的复杂程度往往令人望而却步。不过作为朝夕相处的框架,我们必须得明白一个问题就......
  • Spring 解决循环依赖为什么需要三级缓存,而不是两级缓存?
    ......
  • 植物大战僵尸3.0
    #include<iostream>#include<windows.h>usingnamespacestd;//声明变量DWORDZombiesAddress;HWNDhand=NULL;DWORDpid=0;HANDLEhProcess=NULL;DWORDBaseValue=0;DWORDSunshineAddress=0;DWORDMoneyshineAddress=0;voida();voidchu......
  • Spring的事务实现原理
    Spring事务Spring本身并不实现事务,Spring事务的本质还是底层数据库对事务的支持,没有数据库事务的支持,Spring事务就不会生效。例如:使用JDBC操作数据库,使用事务的步骤主要分为如下5步:第一步:获取连接Connectioncon=DriverManager.getConnection();第二步:开启事务con.setAutoC......
  • 【Spring教程28】Spring框架实战:从零开始学习SpringMVC 之 请求与请求参数详解
    目录1设置请求映射路径1.1环境准备1.2问题分析1.3设置映射路径2请求参数2.1环境准备2.2参数传递2.2.1GET发送单个参数2.2.2GET发送多个参数2.2.3GET请求中文乱码2.2.4POST发送参数2.2.5POST请求中文乱码欢迎大家回到《Java教程之Spring30天快速入门》,本教程所有示例......
  • 在Spring Cloud中使用OpenFeign完成从一个微服务上传到另一个微服务中
    跨服务上传文件,嘿嘿,来一篇实用性高的,本篇将主要完成在Feign中上传文件到另一个微服务中。步骤如下:我们需要在服务提供者和服务消费者的项目中添加相应的依赖:对于服务提供者的项目,你需要添加SpringBoot的Web依赖和SpringCloud的Feign依赖。在pom.xml文件中添加以下依赖:<dependenci......