保姆级教程:手把手教你将若依前后端分离版从Java 8平滑升级到Java 17(含Spring Security 6.2.3适配)

张开发
2026/4/18 5:00:29 15 分钟阅读

分享文章

保姆级教程:手把手教你将若依前后端分离版从Java 8平滑升级到Java 17(含Spring Security 6.2.3适配)
保姆级教程手把手教你将若依前后端分离版从Java 8平滑升级到Java 17含Spring Security 6.2.3适配最近在技术社区看到不少开发者讨论Java 17的新特性尤其是对LTS版本长期支持的期待。作为一个长期使用若依框架的开发者我决定将手头的项目从Java 8升级到Java 17。整个过程花了三天时间踩了不少坑也积累了一些经验。今天就把这个完整的升级过程记录下来希望能帮助到有同样需求的同行。升级Java版本看似简单但实际上涉及到整个技术栈的适配特别是像若依这样集成了Spring Boot、MyBatis Plus、Spring Security等主流框架的系统。我们需要考虑的不仅仅是JDK本身的变更还有依赖库的兼容性、配置语法的变化以及Jakarta EE的迁移问题。1. 环境准备与依赖分析在开始升级之前我们需要做好充分的准备工作。首先确保你的开发环境已经安装了Java 17 JDK我推荐使用Amazon Corretto 17或者OpenJDK 17。可以通过以下命令验证java -version你应该看到类似这样的输出openjdk version 17.0.10 2024-01-16 OpenJDK Runtime Environment (build 17.0.107) OpenJDK 64-Bit Server VM (build 17.0.107, mixed mode)接下来我们需要分析当前项目的依赖树找出可能需要升级的组件。在项目根目录下运行mvn dependency:tree dependency.txt这个命令会把项目的完整依赖树输出到dependency.txt文件中。仔细检查这个文件特别关注以下几个关键依赖Spring Boot版本需要升级到3.x系列Spring Security版本MyBatis Plus版本数据库驱动如MySQL Connector/JServlet API相关依赖常见需要升级的依赖清单Spring Boot: 2.x → 3.2.5Spring Security: 5.x → 6.2.3MyBatis Plus: 3.4.x → 3.5.5MySQL Connector/J: 5.x → 8.1.0Logback: 1.2.x → 1.4.14提示建议在升级前创建一个新的Git分支这样如果升级过程中出现问题可以随时回退。2. 分模块修改POM文件若依前后端分离版通常包含多个模块ruoyi-admin、ruoyi-common、ruoyi-framework等。我们需要逐个模块进行升级。2.1 父POM的修改首先修改父POM中的属性定义这是整个升级过程中最关键的一步。我们需要更新Java版本和主要依赖的版本号properties java.version17/java.version maven.compiler.source17/maven.compiler.source maven.compiler.target17/maven.compiler.target spring-boot.version3.2.5/spring-boot.version mybatis.plus.version3.5.5/mybatis.plus.version tomcat.version10.1.24/tomcat.version logback.version1.4.14/logback.version spring-security.version6.2.3/spring-security.version spring-framework.version6.2.6/spring-framework.version mysql-connector-j.version8.1.0/mysql-connector-j.version jakarta.servlet-api.version6.0.0/jakarta.servlet-api.version mybatis-spring.version3.0.3/mybatis-spring.version /properties然后更新dependencyManagement部分确保所有子模块使用统一的依赖版本dependencyManagement dependencies !-- 阿里数据库连接池 -- dependency groupIdcom.alibaba/groupId artifactIddruid-spring-boot-3-starter/artifactId version${druid.version}/version /dependency !-- servlet -- dependency groupIdjakarta.servlet/groupId artifactIdjakarta.servlet-api/artifactId version${jakarta.servlet-api.version}/version /dependency !-- mysql -- dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId version${mysql-connector-j.version}/version /dependency !-- MyBatis相关 -- dependency groupIdorg.mybatis.spring.boot/groupId artifactIdmybatis-spring-boot-starter/artifactId version${mybatis-spring.version}/version /dependency /dependencies /dependencyManagement2.2 子模块POM的修改ruoyi-admin模块主要需要更新MySQL驱动dependencies !-- Mysql驱动包 -- dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId /dependency /dependenciesruoyi-common模块需要更新Servlet APIdependencies !-- servlet包 -- dependency groupIdjakarta.servlet/groupId artifactIdjakarta.servlet-api/artifactId /dependency /dependenciesruoyi-framework模块需要特别注意Druid连接池的版本dependencies !-- 阿里数据库连接池 -- dependency groupIdcom.alibaba/groupId artifactIddruid-spring-boot-3-starter/artifactId /dependency !-- 验证码 -- dependency groupIdpro.fessional/groupId artifactIdkaptcha/artifactId exclusions exclusion artifactIdservlet-api/artifactId groupIdjakarta.servlet/groupId /exclusion /exclusions /dependency /dependencies注意从Spring Boot 3开始很多依赖的groupId或artifactId发生了变化特别是Jakarta EE相关的包名从javax.改为了jakarta.。3. Spring Security 6.2.3适配Spring Security 6.x相对于5.x有较大的API变化这是升级过程中最具挑战性的部分之一。我们需要重点关注安全配置类的修改。3.1 SecurityConfig的修改最明显的变化是.antMatchers()方法被.requestMatchers()取代。下面是新旧代码对比旧版配置.authorizeRequests() .antMatchers(/login, /register, /captchaImage).permitAll() .antMatchers(HttpMethod.GET, /, /*.html, /**/*.html, /**/*.css, /**/*.js).permitAll() .anyRequest().authenticated();新版配置.authorizeHttpRequests((requests) - { requests.requestMatchers(/login, /register, /captchaImage).permitAll() .requestMatchers(HttpMethod.GET, /, /*.html, /**.html, /**.css, /**.js).permitAll() .anyRequest().authenticated(); })完整的SecurityConfig类修改示例Bean protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { return httpSecurity // CSRF禁用因为不使用session .csrf(AbstractHttpConfigurer::disable) // 禁用HTTP响应标头 .headers(header - header .cacheControl(HeadersConfigurer.CacheControlConfig::disable) .frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)) // 认证失败处理类 .exceptionHandling(exception - exception .authenticationEntryPoint(unauthorizedHandler)) // 基于token所以不需要session .sessionManagement(session - session .sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 注解标记允许匿名访问的url .authorizeHttpRequests((requests) - { permitAllUrl.getUrls().forEach(url - requests.requestMatchers(url).permitAll()); requests.requestMatchers(/login, /register, /captchaImage).permitAll() .requestMatchers(HttpMethod.GET, /, /*.html, /**.html, /**.css, /**.js, /profile/**).permitAll() .requestMatchers(/swagger-ui.html, /swagger-resources/**, /webjars/**, /*/api-docs, /druid/**).permitAll() .anyRequest().authenticated(); }) // 添加Logout filter .logout(logout - logout .logoutUrl(/logout) .logoutSuccessHandler(logoutSuccessHandler)) // 添加JWT filter .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class) // 添加CORS filter .addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class) .addFilterBefore(corsFilter, LogoutFilter.class) .build(); }3.2 PermitAllUrlProperties的修改Spring Security 6.x中获取请求映射的方式也发生了变化Override public void afterPropertiesSet() { // 修改前 // RequestMappingHandlerMapping mapping applicationContext.getBean(RequestMappingHandlerMapping.class); // 修改后 RequestMappingHandlerMapping mapping applicationContext.getBean(requestMappingHandlerMapping, RequestMappingHandlerMapping.class); MapRequestMappingInfo, HandlerMethod map mapping.getHandlerMethods(); map.keySet().forEach(info - { HandlerMethod handlerMethod map.get(info); // 获取方法上边的注解 Anonymous method AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class); Optional.ofNullable(method).ifPresent(anonymous - Objects.requireNonNull(info.getPathPatternsCondition().getPatternValues()) .forEach(url - urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK)))); // 获取类上边的注解 Anonymous controller AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class); Optional.ofNullable(controller).ifPresent(anonymous - Objects.requireNonNull(info.getPathPatternsCondition().getPatternValues()) .forEach(url - urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK)))); }); }4. Jakarta EE迁移与验证从Java EE到Jakarta EE的包名变更是一个重大变化我们需要检查所有javax.的导入并替换为jakarta.。4.1 Servlet API变更修改DruidConfig中的导入语句// 修改前 // import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; // import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties; // 修改后 import com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceBuilder; import com.alibaba.druid.spring.boot3.autoconfigure.properties.DruidStatProperties;4.2 验证升级结果完成所有修改后我们需要验证系统功能是否正常编译验证mvn clean compile确保没有编译错误。单元测试mvn test运行所有单元测试确保核心逻辑仍然正常工作。功能验证启动应用mvn spring-boot:run测试登录功能验证权限控制是否正常检查数据库连接是否正常测试文件上传下载等Servlet相关功能常见问题排查如果遇到ClassNotFound异常检查是否所有javax.的导入都已替换为jakarta.如果Spring Security配置不生效检查是否所有.antMatchers()都已改为.requestMatchers()如果数据库连接失败检查MySQL驱动版本和连接参数提示建议在升级完成后运行完整的回归测试特别是权限相关的功能点。

更多文章