您现在的位置是:首页 >其他 >Spring Boot3.0升级相关问题网站首页其他

Spring Boot3.0升级相关问题

JAVA贩卖机 2024-06-17 11:28:30
简介Spring Boot3.0升级相关问题

Spring Boot 3.0升级相关问题

我是现升级到Spring Boot 2.7.6 后升级到 3.0

原始版本:

springboot 1.5.1.RELEASE + jdk1.8

目标版本:

springboot 3.0 + jdk17

注意事项:

1. org.apache.maven.plugins:maven

​ 前期项目中如果刷新maven时会出现 org.apache.maven.plugins:maven-xxxxxxx 的情况,在maven配置项中加入以下代码

<mirror>
            <id>alimaven</id>
            <name>aliyun maven</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <mirrorOf>central</mirrorOf>
        </mirror>

        <!-- maven官方镜像 -->
        <mirror>
            <id>mirrorId</id>
            <mirrorOf>central</mirrorOf>
            <name>Human Readable Name </name>
            <url>http://repo1.maven.org/maven2/</url>
        </mirror>

        <!-- 阿里云镜像 -->
        <mirror>
            <id>alimaven</id>
            <name>aliyun maven</name>
            <url>http://central.maven.org/maven2</url>
            <mirrorOf>central</mirrorOf>
        </mirror>

        <!-- 阿里云镜像 -->
        <mirror>
            <id>alimaven</id>
            <name>aliyun maven</name>
            <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
            <mirrorOf>central</mirrorOf>
        </mirror>

        <!-- junit镜像地址 -->
        <mirror>
            <id>junit</id>
            <name>junit Address/</name>
            <url>http://jcenter.bintray.com/</url>
            <mirrorOf>central</mirrorOf>
        </mirror>

2.{org.springframework.boot:spring-boot-starter-cloud-connectors:null:jar}: The version cannot be empty.**

​ 如果在升级 Spring Boot 版本时遇到了 org.springframework.boot:spring-boot-starter-cloud-connectors:null:jar 版本为空的错误,可能是由于版本引发的问题。此错误通常发生在将 Spring Boot 1.x 项目升级到 2.x 时。 你可以检查项目中是否有指定 spring-cloud-connectors 的版本,如果没有,可以手动添加依赖,并指定版本。示例 Maven 依赖如下:

  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-cloud-connectors</artifactId>
     <version>2.1.8.RELEASE</version>
  </dependency>

Spring Boot版本差异产生的问题

1.mapstruct** 版本(找不到Mapper注解、Mapping注解)

​ 如果项目中引用 mapstruct 的话,需要要将mapstruct 版本升级至1.4.1以上版本,目前我选择的版本是 1.4.2.Final

​ 同时,我们升级了jdk的版本,那么在原本的依赖中也要进行更改

  <!--    原始版本    -->
		<dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-jdk8</artifactId>
            <version>${mapstruct.version}</version>
        </dependency>
  <!--    新版本   去掉jdk8 即可-->
		<dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${mapstruct.version}</version>
        </dependency>

2.Pageable 接口

​ Pageable接口是spring Data库中定义的一个接口,该接口是所有分页相关信息的一个抽象,通过该接口,我们可以得到和分页相关所有信息(例如pageNumber、pageSize等)。

​ 在这个接口中 getOffset() 方法主要时用于返回要根据基础页和页大小取的偏移量,现在由于版本提升,其返回值由 int 类型转换为 long ,如果代码中引用到这个方法时,需要注意类型转换


3.org.springframework.data.repository.query.QueryByExampleExecutor中的方法 findOne应用到给定类型;

​ 这个是由于版本更换导致的问题,然后我之前在 1.5的版本上调用的是org.springframework.data.repository 包下的,升级后需换为 findById().**orElse(null),因为find.one 是 repository.query包下的,**会出现报错。

同理:delete() 方法也存在问题,如果删除一个deleteById(),如果删除多个,传入集合的方式,采取deleteAll();


4.com.mongodb.client.MongoCollection无法转换为com.mongodb.DBCollection**

DBCollectionmongo-java-driver 包中的一个类,用于操作 MongoDB 数据库中集合(Collection)。自从 MongoDB Java Driver 3.x 发布以来, DBCollection 已经被弃用了,取而代之的是 MongoCollection 类。 你可以使用 MongoCollection 类来替换 DBCollection ,它提供了更好的代码兼容性和更多的功能。下面是一个样例代码,演示如何使用 MongoCollection

// 1. 创建 MongoDB 客户端实例
MongoClient mongoClient = new MongoClient("localhost", 27017);

// 2. 获取数据库
MongoDatabase database = mongoClient.getDatabase("myDb");

// 3. 获取集合
MongoCollection<Document> collection = database.getCollection("myCollection");

// 4. 插入文档
Document doc = new Document("name", "John Doe")
                .append("age", 30)
                .append("email", "johndoe@example.com");
collection.insertOne(doc);

// 5. 查询文档
Document query = new Document("name", "John Doe");
FindIterable<Document> results = collection.find(query);
for (Document result : results) {
    System.out.println(result.toJson());
}

// 6. 更新文档
Document updateQuery = new Document("name", "John Doe");
Document updateDoc = new Document("$set", new Document("age", 35));
UpdateResult updateResult = collection.updateOne(updateQuery, updateDoc);
System.out.println("Update Count: " + updateResult.getModifiedCount());

// 7. 删除文档
Document deleteQuery = new Document("name", "John Doe");
DeleteResult deleteResult = collection.deleteOne(deleteQuery);
System.out.println("Delete Count: " + deleteResult.getDeletedCount());

// 8. 关闭客户端
mongoClient.close();

注意MongoCollection 使用了泛型,你需要指定集合中文档的类型。在上面的样例代码中,我们使用了 Document 类型。如果你想使用自定义的 Java 类型,需要将它映射为 MongoDB 的 BSON 格式。你可以使用 MongoDB 提供的 Codec 接口实现对 Java 类型和 BSON 格式之间的转换。


5.Relaxe*dPropertyResolver 找不到

​ Spring Boot 2.0不是直接使用现有的PropertySource接口进行绑定,而是引入了一个新的ConfigurationPropertySource接口。 我们引入了一个新的接口,为我们提供了一个合理的地方来实施放松绑定规则,这些规则以前是活页夹的一部分接口的主要API非常简单:

// 原来的code:
RelaxedPropertyResolver propertyResolver = 
new RelaxedPropertyResolver(environment, "spring.datasource");
propertyResolver.getSubProperties("....")
    
// 现在的code:
Iterable sources = ConfigurationPropertySources.get(environment);
Binder binder = new Binder(sources);
BindResult bindResult = binder.bind("spring.datasource", Properties.class);
Properties properties= bindResult.get();

6.reids找不到(JedisPool找不到了)

版本升级后,jedis需要重新进行引入

 		<dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.10.2</version>
        </dependency>

备注:版本需要根据自己需要去调整


7.EmbeddedServletContainerCustomizer、UndertowEmbeddedServletContainerFactory接口找不到了

​ 从 Spring Boot 2.0 版本开始, EmbeddedServletContainerCustomizer 接口已过时并且不建议使用。在 Spring Boot 2.0 及以后的版本中,建议使用 WebServerFactoryCustomizer 接口来定制嵌入式 Web 服务器。 如果在升级 Spring Boot 版本后出现 EmbeddedServletContainerCustomizer 接口找不到的问题,可以尝试将其替换为 WebServerFactoryCustomizer 接口,同时 UndertowEmbeddedServletContainerFactory接口可以替换为UndertowServletWebServerFactory,并相应地修改方法签名。以下是一些可能的解决方案:

public class WebConfigurer implements ServletContextInitializer, WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
    @Override
    public void customize(ConfigurableServletWebServerFactory container) {
        MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
        // IE issue, see https://github.com/jhipster/generator-jhipster/pull/711
        mappings.add("html", "text/html;charset=utf-8");
        // CloudFoundry issue, see https://github.com/cloudfoundry/gorouter/issues/64
        mappings.add("json", "text/html;charset=utf-8");
        container.setMimeMappings(mappings);

        /*
         * Enable HTTP/2 for Undertow - https://twitter.com/ankinson/status/829256167700492288
         * HTTP/2 requires HTTPS, so HTTP requests will fallback to HTTP/1.1.
         * See the JHipsterProperties class and your application-*.yml configuration files
         * for more information.
         */
        if (jHipsterProperties.getHttp().getVersion().equals(JHipsterProperties.Http.Version.V_2_0)) {
            if (container instanceof UndertowServletWebServerFactory) {
                ((UndertowServletWebServerFactory) container)
                    .addBuilderCustomizers((builder) -> {
                        builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true);
                    });
            }
        }
    }
    
}

8.ExportMetricReader、ExportMetricWriter注解找不到了

在Spring Boot 2.7中,确实已经移除了 @ExportMetrics@ExportMetricWriter 注解。如果要导出自定义的 MeterRegistry 实例以供给其他 Bean 使用,可以考虑使用 MeterRegistryPostProcessor 接口或 MeterRegistryCustomizer 接口。 MeterRegistryPostProcessor 接口用于在容器加载 MeterRegistry 实例时进行后处理,可以通过它来将 MeterRegistry 实例导出到其他组件中。以下是一个示例:

@Configuration
public class MyMetricsConfig {
     @Bean
    public PrometheusMeterRegistry myMeterRegistry() {
        return new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
    }
     @Bean
    public MeterRegistryPostProcessor myMeterRegistryPostProcessor(PrometheusMeterRegistry myMeterRegistry) {
        return (registry) -> {
            registry.add(myMeterRegistry);
        };
    }
}
 @Service
@MicrometerMetrics
public class MyService {
     private final MeterRegistry meterRegistry;
     @Autowired
    public MyService(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }
     // ...
}

​ 在上面的示例中, MyMetricsConfig 配置类中定义了一个名为 myMeterRegistryPrometheusMeterRegistry 实例,并通过 myMeterRegistryPostProcessor 方法创建了一个 MeterRegistryPostProcessor 实例,将 myMeterRegistry 导出到其他组件中。 MeterRegistryCustomizer 接口用于在容器加载 MeterRegistry 实例时进行后处理,可以通过它来定制 MeterRegistry 实例的一些属性。以下是一个示例:

@Configuration
public class MyMetricsConfig {
     @Bean
    public PrometheusMeterRegistry myMeterRegistry() {
        return new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
    }
     @Bean
    public MeterRegistryCustomizer<PrometheusMeterRegistry> myMeterRegistryCustomizer() {
        return (registry) -> {
            registry.config().commonTags("application", "myapp");
        };
    }
}
 @Service
@MicrometerMetrics
public class MyService {
     private final MeterRegistry meterRegistry;
     @Autowired
    public MyService(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }
     // ...
}

​ 在上面的示例中, MyMetricsConfig 配置类中定义了一个名为 myMeterRegistryPrometheusMeterRegistry 实例,并通过 myMeterRegistryCustomizer 方法创建了一个 MeterRegistryCustomizer 实例,增加了一个名为 application 值为 myapp 的通用标签。


9.JmxReporter类找不到

缺少一个JmxReporter这个类,同时是在com.codahale.metrics这个包中

直接导入一个依赖就可以解决

<dependency>
	<groupId>com.codahale.metrics</groupId>
	<artifactId>metrics-core</artifactId>
	<version>3.0.2</version>
</dependency>

10.getErrorAttributes()方法被改写

​ 在Spring Boot 2.7中, getErrorAttributes() 方法已经被移除,推荐使用 getErrorAttributes(WebRequest, ErrorAttributeOptions) 方法。 getErrorAttributes(WebRequest, ErrorAttributeOptions) 方法的返回值类型为 MapErrorAttributeOptions 是一个枚举类型,表示错误属性的选项,可以使用 ErrorAttributeOptions.defaults() 方法获取默认的选项值。可以在选项中设置是否包含堆栈跟踪信息、异常类型等信息。 下面是一个使用 getErrorAttributes(WebRequest, ErrorAttributeOptions) 方法的示例代码:

@ControllerAdvice
public class MyErrorController implements ErrorController {
    private static final String PATH = "/error";
    @Override
    public String getErrorPath() {
        return PATH;
    }
    @RequestMapping(PATH)
    public ResponseEntity<Map<String, Object>> error(WebRequest webRequest) {
        ErrorAttributeOptions options = ErrorAttributeOptions.defaults()
                .including(ErrorAttributeOptions.Include.STACK_TRACE);
        Map<String, Object> errorAttributes = new DefaultErrorAttributes()
                .getErrorAttributes(webRequest, options);
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorAttributes);
    }
}

​ 在上面的代码中,我们重写了 ErrorController 接口的 getErrorPath() 方法,指定了错误端点的路径为 /error 。在 error() 方法中,我们创建了一个 ErrorAttributeOptions 对象,并指定了包含堆栈跟踪信息。然后使用 DefaultErrorAttributes 的实例调用 getErrorAttributes(WebRequest, ErrorAttributeOptions) 方法获取错误属性,最后使用 ResponseEntity 返回错误属性 Map 。 需要注意的是, DefaultErrorAttributes 是一个默认的错误属性解析器,它将错误信息解析成一个 Map 对象。如果需要自定义错误属性,可以创建一个实现了 ErrorAttributes 接口的类,并在控制器中使用。


11.MultipartConfigFactory类中上传数据大小改写

//原始的方法中我们可以直接定义
MultipartConfigFactory factory = new MultipartConfigFactory();
 factory.setMaxFileSize("100MB");
 factory.setMaxRequestSize("100MB");
//现在要进行改写
factory.setMaxFileSize( DataSize.parse("100", DataUnit.MEGABYTES));
factory.setMaxRequestSize( DataSize.parse("100", DataUnit.MEGABYTES));

  1. PageRequest 类的构造方法从公共访问权限变为了受保护的访问权限

    PageRequest 类的构造方法从公共访问权限变为了受保护的访问权限,不再可以直接外部调用。如果你之前的代码中使用到了 PageRequest 的构造方法,需要进行如下修改:

    可以使用其静态方法 PageRequest.of() 和 new PageReques()效果一致

    1. 首先,创建一个继承自 PageRequest 的子类,如下所示:
public class CustomPageRequest extends PageRequest {

    public CustomPageRequest(int page, int size) {
        super(page, size);
    }

    public CustomPageRequest(int page, int size, Sort.Direction direction, String... properties) {
        super(page, size, direction, properties);
    }
}

在这个子类中,我们继承了 PageRequest ,并且提供了两个构造方法,可以通过这两个构造方法来创建新的分页请求对象。 2. 然后,在之前使用 PageRequest 的地方,替换为使用我们创建的 CustomPageRequest ,如下所示:

Pageable pageable = new CustomPageRequest(pageNumber, pageSize);

或者:

Pageable pageable = new CustomPageRequest(pageNumber, pageSize, Sort.Direction.ASC, "id");

这样就可以在你的代码中继续使用分页请求对象了。需要注意的是,如果你的代码中创建分页请求对象的地方比较多,那么需要替换所有的地方。

同理 sort 类也发生了改变 ,举例:

//之前的写法
 Sort sort = new Sort( direction,  properties)
//现在可通过静态调用 
  by(Sdirection, properties);
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。