关于若依升级到springboot3并编译成exe可执行文件的尝试一

797 阅读3分钟

若依升级到springboot3

声明:本文章为学习总结,不合理和错误之处还请指正

本文使用到的若依为前后分离版,JDK必须>=17

pom文件及相关依赖的变更

<java.version>17</java.version>

1. springboot使用3.1.0版本

<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>3.1.0</version>
   <relativePath />
</parent>

2. druid版本更新到1.2.18并使用druid-spring-boot-3-starter

<druid.version>1.2.18</druid.version>

旧版本

<!-- 阿里数据库连接池 -->
<dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid-spring-boot-starter</artifactId>
          <version>${druid.version}</version>
      </dependency>

新版本

<!-- 阿里数据库连接池 -->
<dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid-spring-boot-3-starter</artifactId> 
          <version>${druid.version}</version>
</dependency>

在src/main/resources/META-INF目录下创建spring文件夹和org.springframework.boot.autoconfigure.AutoConfiguration.imports文件 imports文件内容为com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceAutoConfigure

image.png

3. pom文件添加新依赖

<dependency>
   <groupId>org.springdoc</groupId>
   <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
   <version>2.0.2</version>
</dependency>

4.替换新的quartz依赖

旧版本

<!-- 定时任务 -->
<dependency>
   <groupId>org.quartz-scheduler</groupId>
   <artifactId>quartz</artifactId>
   <exclusions>
      <exclusion>
         <groupId>com.mchange</groupId>
         <artifactId>c3p0</artifactId>
      </exclusion>
   </exclusions>
</dependency>

新版本

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

5.新增javax.xml.bind依赖

<jaxb-api.version>2.3.0</jaxb-api.version>
<dependency>
   <groupId>javax.xml.bind</groupId>
   <artifactId>jaxb-api</artifactId>
   <version>${jaxb-api.version}</version>
</dependency>

6.jaxb-api更新版本

<pagehelper.spring.boot.starter.version>1.4.6</pagehelper.spring.boot.starter.version>

代码的变更

1.javaee转jakara

SpringBoot3开始,所有的Java EE Api都需要迁移到Jakarta EE上来,需要jakarta替换原先报红的javax

idea提供了该功能: 561372-20230220191853119-464254843.png

2.SecurityConfig文件修改

类上注解过期需更新,删除 extends WebSecurityConfigurerAdapter

旧版本

@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter

新版本

@Configuration
@EnableWebSecurity
public class SecurityConfig

旧版本

/**
 * 解决 无法直接注入 AuthenticationManager
 *
 * @return
 * @throws Exception
 */
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
{
    return super.authenticationManagerBean();
}

新版本

@Bean
AuthenticationManager authenticationManager(
        AuthenticationConfiguration authenticationConfiguration) throws Exception {
    return authenticationConfiguration.getAuthenticationManager();
}

旧版本

/**
 * anyRequest          |   匹配所有请求路径
 * access              |   SpringEl表达式结果为true时可以访问
 * anonymous           |   匿名可以访问
 * denyAll             |   用户不能访问
 * fullyAuthenticated  |   用户完全认证可以访问(非remember-me下自动登录)
 * hasAnyAuthority     |   如果有参数,参数表示权限,则其中任何一个权限可以访问
 * hasAnyRole          |   如果有参数,参数表示角色,则其中任何一个角色可以访问
 * hasAuthority        |   如果有参数,参数表示权限,则其权限可以访问
 * hasIpAddress        |   如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问
 * hasRole             |   如果有参数,参数表示角色,则其角色可以访问
 * permitAll           |   用户可以任意访问
 * rememberMe          |   允许通过remember-me登录的用户访问
 * authenticated       |   用户登录后可访问
 */
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception
{
    httpSecurity
            // CSRF禁用,因为不使用session
            .csrf().disable()
            // 认证失败处理类
            .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
            // 基于token,所以不需要session
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
            // 过滤请求
            .authorizeRequests()
            // 对于登录login 注册register 验证码captchaImage 允许匿名访问
            .antMatchers("/login", "/register", "/captchaImage").anonymous()
            .antMatchers(
                    HttpMethod.GET,
                    "/",
                    "/*.html",
                    "/**/*.html",
                    "/**/*.css",
                    "/**/*.js",
                    "/profile/**"
            ).permitAll()
            .antMatchers("/swagger-ui.html").anonymous()
            .antMatchers("/swagger-resources/**").anonymous()
            .antMatchers("/webjars/**").anonymous()
            .antMatchers("/*/api-docs").anonymous()
            .antMatchers("/druid/**").anonymous()
            // 除上面外的所有请求全部需要鉴权认证
            .anyRequest().authenticated()
            .and()
            .headers().frameOptions().disable();
    httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
    // 添加JWT filter
    httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
    // 添加CORS filter
    httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class);
    httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class);
}

新版本(注意新的spring已经弃用了AntPath配置模式,默认使用pathPattern;pathPattern无法使用 ** 匹配任意层级目录,以下都改为一个 *

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
            .authorizeHttpRequests((authorize) -> authorize
                    .requestMatchers("/login", "/register", "/captchaImage").anonymous()
                    .requestMatchers(
                            HttpMethod.GET,
                            "/",
                            "/*.html",
                            "/*/*.html",
                            "/*/*.css",
                            "/*/*.js",
                            "/profile/*").permitAll()
                    .requestMatchers("/swagger-ui.html","/swagger-resources/*","/webjars/*","/*/api-docs","/druid/*").anonymous()
                    .anyRequest().authenticated()

            )
            // CSRF禁用,因为不使用session
            .csrf(csrfConfigurer -> csrfConfigurer.disable()
            )
            // 认证失败处理类
            .exceptionHandling(exceptionConfigurer -> exceptionConfigurer.authenticationEntryPoint(unauthorizedHandler))
            // 基于token,所以不需要session
            .sessionManagement(sessionConfigurer -> sessionConfigurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .headers(headersConfigurer -> headersConfigurer.frameOptions(frameOptionsConfig -> frameOptionsConfig.disable()))
            .logout(httpSecurityLogoutConfigurer -> httpSecurityLogoutConfigurer.logoutSuccessHandler(logoutSuccessHandler))
            .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
            // 添加CORS filter
            .addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class)
            .addFilterBefore(corsFilter, LogoutFilter.class)
            ;

    return http.build();
}

注释该方法

/**
 * 身份认证接口
 */
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
    auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}

3.ResourcesConfig文件修改

旧版本

// 设置访问源地址
config.addAllowedOrigin("*");

新版本

// 设置访问源地址
config.addAllowedOriginPattern("*");

4.quartz 配置修改

不使用ScheduleConfig类,可注释

在DruidConfig文件中dynamicDataSource的bean上加入@QuartzDataSource注解 新版本

@Bean(name = "dynamicDataSource")
@QuartzDataSource
@Primary
public DynamicDataSource dataSource(DataSource masterDataSource)
{
    Map<Object, Object> targetDataSources = new HashMap<>();
    targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);
    setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource");
    return new DynamicDataSource(masterDataSource, targetDataSources);
}

到这里,应该就可以运行了。

下篇文章再总结natvie-image的使用。