SpringBoot3.0 迁移

SpringBoot2.0 迁移 SpringBoot3.0

最近Springboot3.0正式版发布了,Spring Framework也升级到了6.0,JavaEE也由旧的Oracle发布的JavaEE升级为Eclipse发布的JakartaEE。

Springboot3.0开始仅支持OpenJDK17及更高版本的OpenJDK,OpenJDK17是一个LTS版本。

考虑到Jdk8已经是一个发布快十年的Jdk,且OpenJDK17发布了很多提升效率的新特性,因此我再看到Springboot3.0正式版发布后,也将我的开源项目springboot-project-seed的依赖整体进行了升级。

依赖对比

IDEA: IntelliJ IDEA 2022.3.2 (Community Edition)

软件旧版本新版本
JDKOpenJDK8OpenJDK17
springboot2.3.7.RELEASE3.0.2
spring-cloud bomnull2022.0.1
spring-data bomnull2022.0.1
mybatis-mapper bomnull2.1.0
knife4j-dependencies bomnull4.0.0

问题与解决方案

sun.misc.Cleaner被转移到jdk.internal.ref.Cleaner

旧的伪代码:

java.nio.MappedByteBuffer buffer = null;
sun.misc.Cleaner cleaner = ((sun.nio.ch.DirectBuffer) buffer).cleaner();
cleaner.clear();

新的伪代码:

java.nio.MappedByteBuffer buffer = null;
jdk.internal.ref.Cleaner cleaner = ((sun.nio.ch.DirectBuffer) buffer).cleaner();
cleaner.clear();

JavaEE to JakartaEE

程序中的包依赖涉及javax.*需修改为jakarta.*。

常见需要修改的类:

备注
javax.validation.Validjakarta.validation.Valid校验框架validation下的类均需要修改
javax.validation.constraints.NotBlankjakarta.validation.constraints.NotBlank校验框架validation下的类均需要修改
javax.servlet.ServletRequestjakarta.servlet.ServletRequesttomcat下的类均需要修改
javax.servlet.http.HttpServletRequestjakarta.servlet.http.HttpServletRequesttomcat下的类均需要修改
javax.servlet.http.Cookiejakarta.servlet.http.Cookietomcat下的类均需要修改
javax.annotation.Resourcejakarta.annotation.Resourceannotation-api下的类均需要修改

验证存在的Deprecated

备注
org.springframework.web.servlet.handler.HandlerInterceptorAdapterorg.springframework.web.servlet.HandlerInterceptorOpenJDK1.8的interface支持默认方法后spring的很多抽象适配器类被标记为@Deprecated
com.fasterxml.jackson.databind.PropertyNamingStrategy.SNAKE_CASEcom.fasterxml.jackson.databind.PropertyNamingStrategies.SNAKE_CASE
org.springframework.scheduling.annotation.AsyncConfigurerSupportorg.springframework.scheduling.annotation.AsyncConfigurerOpenJDK1.8的interface支持默认方法后spring的很多抽象配置类被标记为@Deprecated
org.springframework.http.client.ClientHttpResponse.getStatusCode().getReasonPhrase()org.springframework.http.client.ClientHttpResponse.getStatusText()旧的方法被删除
org.springframework.web.socket.messaging.WebSocketStompClient.connectorg.springframework.web.socket.messaging.WebSocketStompClient.connectAsync

tk-mybatis升级为mybatis-mapper

tk-mybatis已经停止维护,要使用mybatis增强组件需迁移到mybatis-mapper 2.1.0。

旧的依赖:

<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper-spring-boot-starter</artifactId>
    <version>2.1.5</version>
</dependency>

新的依赖:

<dependency>
    <groupId>io.mybatis</groupId>
    <artifactId>mybatis-service</artifactId>
    <version>2.1.0</version>
</dependency>

mybatis-mapper为tk-mybatis作者基于mybatis-3.5.9开发的全新的mybatis增强组件,支持lambda表达式,优化了查询api,更多信息

tk.mybatis.spring.annotation.MapperScan注解被删除,新的mybatis-service中使用org.mybatis.spring.annotation.MapperScan注解。

CORS配置

allowCredentials设置为true,必须使用allowedOriginPatterns。

http

旧的配置:

@Override
public void addCorsMappings(CorsRegistry registry) {

    registry.addMapping("/**")
        .allowedOrigins("*")
        .allowCredentials(true)
        .allowedHeaders("*")
        .allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH", "OPTIONS")
        .maxAge(3600L);
}

新的配置:

@Override
public void addCorsMappings(CorsRegistry registry) {

    registry.addMapping("/**")
        .allowedOriginPatterns("*")
        .allowCredentials(true)
        .allowedHeaders("*")
        .allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH", "OPTIONS")
        .maxAge(3600L);
}
websocket

旧的配置:

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint(endpoint)
        .setAllowedOrigins("*") // 解决跨域问题
        .withSockJS()
        .setInterceptors(new HttpSessionIdHandshakeInterceptor());
}

新的配置:

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint(endpoint)
        .setAllowedOriginPatterns("*") // 解决跨域问题
        .withSockJS()
        .setInterceptors(new HttpSessionIdHandshakeInterceptor());
}

websocket headers

header的容器由LinkedList修改为了ArrayList。

旧的伪代码:

@Override
public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
    Map<?, ?> nativeHeadersMap = (Map<?, ?>) message.getHeaders().get(NATIVE_HEADERS);

    LinkedList<?> idList = (LinkedList<?>) nativeHeadersMap.get("id");
    if (idList != null) {
        String idString = idList.get(0).toString();
    }
}

新的伪代码:

@Override
public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
    Map<?, ?> nativeHeadersMap = (Map<?, ?>) message.getHeaders().get(NATIVE_HEADERS);

    List<?> idList = (List<?>) nativeHeadersMap.get("id");
    if (idList != null) {
        String idString = idList.get(0).toString();
    }
}

路径匹配

Spring Framework 6.0的Spring MVC和Spring Webflux路径匹配规则发生了变化,默认情况下头部和尾部斜杠/的匹配机制将和以前不同。

6.0以前/foo/bar等同于/foo/bar/,6.0以后/foo/bar不同于/foo/bar/

假设
spring.application.name=sps
api-prefix=/api/kyyee/v2/${spring.application.name}

旧的伪代码:

@RequestMapping("${api-prefix}/employees)

新的伪代码:

@RequestMapping("/${api-prefix}/employees)

如路径匹配涉及以上类似写法,必须在头部添加斜杠/,否则在访问相关uri时,程序将响应404。

spring.data

spring.data前缀已被保留给Spring Data相关的项目,如果使用了Spring Data相关项目,application.yml中相关的配置需要修改。例如 spring.redis 现在需要修改为 spring.data.redis。
旧的伪代码:

spring:
    redis:
        url: redis://${REDIS_USERNAME}:${REDIS_PASSWORD}@${REDIS_URL}
        timeout: 1000ms
        jedis:
            pool:
                max-active: 100
                max-idle: 10
                max-wait: -1ms
                min-idle: 1

新的伪代码:

spring:
    data:
        redis:
            url: redis://${REDIS_USERNAME}:${REDIS_PASSWORD}@${REDIS_URL}
            timeout: 1000ms
            jedis:
                pool:
                    max-active: 100
                    max-idle: 10
                    max-wait: -1ms
                    min-idle: 1

springfox to springdoc

swagger的spring增强组件springfox已停止维护,且不再支持springboot3.0,因此采用全新推出的springdoc作为swagger的spring增强组件,该组件提供了对OpenApi3.0的支持。

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
    <version>4.0.0</version>
</dependency>

knife4j是一款更适合Chinese Coder的swagger-ui组件,引入上述依赖将自动引入springdoc相关的依赖。springboot3需要的knife4j-openapi3-jakarta-spring-boot-starter最低版本为4.0.0,springdoc最低版本为2.0.0。

OpenApi3.0对比Swagger2.0的注解由较大的变更,参考下表:

备注
@Api@Tag
@ApiIgnore@Parameter(hidden=true) or @Operation(hidden=true) or @Hidden
@ApiImplicitParam@Parameter
@ApiImplicitParams@Parameters
@ApiModel@Schema
@ApiModelProperty(hidden=true)@Schema(accessMode=READ_ONLY)
@ApiModelProperty@Schema
@ApiOperation(value=“foo”, notes=“bar”)@Operation(summary=“foo”, description=“bar”)
@ApiParam@Parameter
@ApiResponse(code=404, message=“foo”)@ApiResponse(responseCode=“404”, description=“foo”)

springfox迁移指南

Github

开源项目springboot-project-seed已完成 springboot 2.3.7.RELEASE 到 springboot 3.0.2 升级,欢迎 issue、star。

附录

参考SpringBoot3.0的发布日志,Spring Boot 3.0 Release Notes or Spring Boot 3.0 Migration Guide

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值