如何将项目迁移至 Spring Boot 2.0 ?

Posted Java后端

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将项目迁移至 Spring Boot 2.0 ?相关的知识,希望对你有一定的参考价值。

点击上方 蓝色字体 ,选择“置顶公众号”
优质文章,第一时间送达
作者 |  oschina
链接 | oschina.net/translate/spring-boot-2-0-migration-guide

前言

官方宣布于 2019/08/01 不再更新维护 Spring Boot 1.5x 版本,建议迁移到2.0。近日有读者询问久一如何进行迁移,其实官方早就发布文档供开发者参考迁移,发布的是英文文档,国内一大批翻译爱好者对此文档进行了翻译。

参与本篇文章翻译的开发者有:Tocy,dreamanzhao,Tot_ziens,浪子_仗剑走天涯,溪边九节,DAOYUAN0626,360linker,kukaqin,Dpound0。

本文档主要通过开发指南的方式来帮助您将应用程序迁移到 Spring Boot 2.0。

在你开始之前

首先,Spring Boot 2.0.0 要求 Java 8 或更高版本,不再支持 Java 6 和 7。

在 Spring Boot 2.0 中,许多配置属性已被重命名或被删除,相应地,开发者需要升级他们的 application.properties/application.yml。为了方便升级,Spring Boot 发布了一个新的 spring-boot-properties-migrator 模块。只要将其作为依赖添加到项目中,它不仅会分析应用程序的环境并在启动时打印诊断信息,而且还会在运行时为项目临时迁移属性。在您的应用程序迁移期间,这个模块是必备的:

 
   
   
 
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-properties-migrator</artifactId></dependency>

注意:迁移完成之后,请确保从项目的依赖关系中移除该模块。

如果你想查看具体内容,请参阅以下资源,或者继续阅读下一节。

Spring Boot 2.0.0 发布说明
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0.0-Release-Notes
使用 Java 9 运行 Spring Boot
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-with-Java-)

构建你的 Spring Boot 应用

Spring Boot 的 Maven 插件

为保持一致性,以及避免与其它插件的冲突,现在暴露的插件配置属性都以 spring-boot 为前缀。

例如,使用下面的命令行能启用名字为 foo 的配置文件:

 
   
   
 
mvn spring-boot:run -Dspring-boot.run.profiles=foo

Surefire 插件的默认值

惯用的 include/exclude 配置模式已经和最新的 Surefire 插件默认集成。如果依赖于此插件,需要相应地更新插件配置。之前对应的配置如下:

 
   
   
 
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <includes> <include>**/*Tests.java</include> <include>**/*Test.java</include> </includes> <excludes> <exclude>**/Abstract*.java</exclude> </excludes> </configuration></plugin>

注意:如果你使用的是 JUnit 5 版本,你应该将 Surefire 降级到 2.19.1 版本。**/*Tests.java  模式不包含在此版本,所以如果你依赖于它,请确保在你已配置文件中将其添加。

注意:如果你使用的是 JUnit 5 版本,你应该将 Surefire 降级到 2.19.1 版本。**/*Tests.java  模式不包含在此版本,所以如果你依赖于它,请确保在你已配置文件中将其添加。

Spring Boot 的 Gradle 插件

Spring Boot 的 Gradle 插件经过了重大的重写,并带来了大量的改进。你可以通过参阅手册和 api 文档以了解插件的功能。

依赖管理

Spring Boot 的 Gradle 插件不再自动应用依赖管理插件。与之代替的是,Spring Boot 的插件现在可以通过导入正确版本的 spring-boot-dependencies bom 来应用依赖管理插件。当依赖管理被配置的时候,这一点会让你有更多的控制权。

对于大多数应用程序,使用应用依赖管理插件就足够了:

 
   
   
 
apply plugin: 'org.springframework.boot'apply plugin: 'io.spring.dependency-management' // <-- 添加这个到你的 build.gradle

注意:依赖管理插件仍然是 spring-boot-gradle-plugin 的传递依赖项,所以不需要在 buildscript 配置中将其列为类路径依赖项。

构建可执行的 jar 和 war

bootRepackage 任务已经被替换成 bootJar 和 bootWar 任务,分别用于构建可执行的 jar 包和 war 包。

配置更新

BootRun、BootJar 和 BootWar 任务现在都使用 mainClassName 作为属性来配置主类的名称。这使得三个特定于引导的任务相互一致,并将其与 Gradle 自己的应用程序插件进行对齐。             

Spring Boot 特性

默认动态代理策略

Spring Boot现在默认使用CGLIB动态代理(基于类的动态代理), 包括AOP. 如果需要基于接口的动态代理(JDK基于接口的动态代理) , 需要设置spring.aop.proxy-target-class属性为false.

SpringApplication

Web Environment

Spring Boot 应用现状可以运行于更多的模式, 所以spring.main.web-environment属性现在不赞成使用, 可以使用spring.main.web-application-type提供更多功能.

如果想让应用以非web服务方式启动, 需要更改属性值:

 
   
   
 
spring.main.web-application-type=none

Tip:可以通过SpringApplication的setWebApplicationType方法实现

Spring Boot 应用时间变更

我们提供了一个新的事件(event)-ApplicationStartedEvent. ApplicationStartedEvent在context刷新之后, 应用或命令行调用之前发送(send). ApplicationReadyEvent在应用活命令行调用之后发送. 表名应用以准备好提供服务。

参考 updated reference documentation.(https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-application-events-and-listeners)

Banner

我们想要减少Spring Boot使用的命名空间数量, banner-related属性迁移到spring.banner.

外部化配置

Relaxed binding 宽松绑定

有关宽松绑定的规则已经收紧。我们假设有一个的acme.my-project.my-name属性:

1. 所有前缀必须是kebab格式(小写,连字符分隔),acme.myProject或acme.my_project是无效的 - 你必须在此处使用acme.my-project

2. 属性名称可以使用kebab-case(my-name),camel-case(myName)或snake-case(my_name)

3. 环境属性(来自OS环境变量)必须使用常规的大写下划线格式,其中下划线只能用于分隔关键词的各个部分,ACME_MYPROJECT_MYNAME      

新的宽松绑定有若干优势:

-只要键值是按照标准格式定义的,就无需担忧在 @ConditionalOnProperty: 中键值的结构,被支持的宽松的变量将会自动透明的工作。

- 如果你正在使用 prefix 属性,你可以简单地通过使用 name 或者value 属性 放入全键值。

-源于Environment 关注自动化,RelaxedPropertyResolver 将不再可用:env.getProperty("com.foo.my-bar") 将找到一个 com.foo.myBar 属性。

org.springframework.boot.bind 包将不再可用,现被 new relaxed binding infrastructure 替换。

特别是,RelaxedDataBinder 相关的应用方式被替换为新的绑定API。下面的列子实现一个 com.foo 为前缀的配置到一个 POJO。

 
   
   
 
new Binder(ConfigurationPropertySources.from(propertySource)) .bind("com.foo", Bindable.of(target)))

由于现在内置了轻松绑定,因此只要使用其中一种支持的格式,就可以请求任何属性而不必关心案例:

 
   
   
 
FlagType flagType = Binder.get(environment) .bind("acme.app.my-flag", FlagType.class) .orElse(FlagType.DEFAULT);

@ConfigurationProperties 校验

如果要打开校验,需要在@ConfigurationProperties 对象上添加注解@Validated。

Configuration location 配置位置

spring.config.location 配置的实现已经配置设定;基于提前添加一个位置到默认配置列表,现在它替换了 默认配置。

如果你是按照以前的方式进行处理,你应该使用spring.config.additional-location进行替换。                                                                

开发网页应用

嵌入式容器封装结构

为了支持响应式的使用案例,嵌入式容器封装结构已经很大程度上进行重构。EmbeddedServletContainer已经被重命名为WebServer, 同时org.springframework.boot.context.embedded包已经被迁移至org.springframework.boot.web.embedded。例如,如果你之前使用TomcatEmbeddedServletContainerFactory回调接口来自定义嵌入式的Tomcat容器,现在你应该使用TomcatServletWebServerFactory。

Servlet-specific的关于server的属性

一些Servlet-specific已经移动到server.servlet的server.*属性:

如何将项目迁移至 Spring Boot 2.0 ?

作为传递性依赖的Web Starter

先前一些Spring Boot Starter是依赖于Spring MVC的 spring-boot-starter-web。在Spring WebFlux的新的支持下,spring-boot-starter-mustache, spring-boot-starter-freemarker 和spring-boot-starter-thymeleaf不再依赖它了。选择并添加spring-boot-starter-web 或spring-boot-starter-webflux是开发者的职责。       

模板引擎

Mustache模板默认的文件扩展名

Mustache模板的文件扩展名曾经是.html。现在的扩展名为.mustache,与官方规格和大多数的IDE插件保持一致。你可以通过更改spring.mustache.suffix配置文件的configuration key来重写这个新的默认值。

Jackson/JSON支持

在2.0版本,我们已经设置Jackson配置文件的默认值,将ISO-8601 strings写作了JSR-310。如果你希望返回之前的设置,可以添加spring.jackson.serialization.write-dates-as-timestamps=true 到你的配置文件中。

一个新的spring-boot-starter-json starter收集了必要的位去读写JSON。它不仅提供了jackson-databind,而且提供了和Java8一起运作的时候相当有用的组件:jackson-datatype-jdk8, jackson-datatype-jsr310 和jackson-module-parameter-names。如果你曾经手动地依赖这些组件,现在可以依赖这个新的starter取代。          

符合默认行为变化的Spring MVC路径

我们已经决定更改默认关于Spring MVC应用的后缀路径(看#11105)。这个性质已经不再默认启动,请参照best practice documented in Spring Framework:https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-requestmapping-suffix-pattern-match

如果你的应用期望像 "GET /projects/spring-boot.json" 这样的请求可以被映射到@GetMapping("/projects/spring-boot"),这一变化正在影响你。

有关的更多信息和如何减少这种变化,请参考 Spring Boot有关路径匹配和内容协商的参考文档:

https://docs.spring.io/spring-boot/docs/2.0.0.RC1/reference/html/boot-features-developing-web-applications.html#boot-features-spring-mvc-pathmatch

Servlet过滤器

现在Servlet过滤器默认的dispatcher控制器类型是DipatcherType.REQUEST;这个Spring Boot的默认值与Servlet specification的默认值保持一致。如果你想要映射一个过滤器到其它的控制器类型,请使用FilterRegistrationBean注册你的过滤器。

注意:Spring Security和Spring Session过滤器是用来配置 ASYNC, ERROR, 和REQUEST的控制器类型。

RestTemplateBuilder

requestFactory(ClientHttpRequestFactory) 被替换成一个新的requestFactory(Supplier<ClientHttpRequestFactory> requestFactorySupplier). Supplier接口允许每个template使用自己的request factory创建, 从而避免了共享一个工厂方法的不良影响. 参考 #11255.

WebJars Locator

Spring Boot 1.x 提供的org.webjars:webjars-locator. webjars-locator依赖管理是 "poorly named library … that wraps the webjars-locator-core project". org.webjars:webjars-locator依赖应替换成org.webjars:webjars-locator-core.

安全性

Spring Boot 2 极大地简化了默认的安全配置,并且使得新增自定义安全性简单了。不是说Spring Boot 2有一些安全相关的自动配置,而是现在拥有一个单独的避让行为,一旦你添加你自己的WebSecurityConfigurerAdapter。

如果你使用任何如下属性,都会受到影响:

 
   
   
 
security.basic.authorize-modesecurity.basic.enabledsecurity.basic.pathsecurity.basic.realmsecurity.enable-csrfsecurity.headers.cachesecurity.headers.content-security-policysecurity.headers.content-security-policy-modesecurity.headers.content-typesecurity.headers.framesecurity.headers.hstssecurity.headers.xsssecurity.ignoredsecurity.require-sslsecurity.sessions

注意:如果你想知道更多关于改变的内容,参考安全迁移用例的wiki页面。

默认的安全性

安全自动配置尽可能地不再显示选项,不再使用Spring Security的默认值。因为那样一个显着的弊端是使用Spring安全的授权内容协商(form login属性)。

默认的用户

Spring Boot默认配置一个单独的用户,拥有生成的密码。该用户可以使用spring.security.user.*下的属性来配置。去进一步定义用户或增加其它用户,你必须暴露一个UserDetailsService bean来取代。示例。

AuthenticationManager bean

如果你想要暴露Spring Security的AuthenticationManager作为一个bean,在你的WebSecurityConfigurerAdapter重写authenticationManagerBean方法, 并且加上@Bean注解。         

Oauth2

Spring Security OAuth项目的功能正在迁移到核心Spring Security。不再为依赖关系提供依赖管理,Spring Boot 2通过Spring Security 5提供OAuth 2.0客户端支持。

如果您依赖尚未迁移的Spring Security OAuth功能,则需要为org.springframework.security.oauth.boot 添加依赖项。我们还继续支持Spring Boot 1.5,以便旧版应用程序可以继续使用它,直到提供升级路径。

Actuator Security

执行器不再有单独的安全自动配置(management.security.* 这种属性配置会被取消)。 每个endpoint 的敏感标志也没有在安全配置中变得更加明确。 如果您依赖于此行为,则需要创建或调整您的安全配置,便于保护你的endpoint 的安全策略。

例如,你有一下配置文件

 
   
   
 
endpoints.flyway.sensitive=falseendpoints.info.sensitive=truemanagement.security.roles=MY_ADMIN
 
   
   
 
http .authorizeRequests() .requestMatchers(EndpointRequest.to("health", "flyway")).permitAll() .requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("MY_ADMIN")

请注意,在2.x中,默认情况下 health 和info 是可以被访问的,(默认情况下 health 的详细信息不能被访问显示)。 为了与这些新的默认值保持一致,health 已被添加到首要的mather中。

使用关系型数据库

配置DataSource

默认的数据库连接池由Tomcat换成HikariCP. 如果在一个Tomcat应用中用spring.datasource.type来强制使用Hikari连接池, 则可以去掉这个override.

提示 open-in-view 的警告信息

从现在开始, 没有明确的启动spring.jpa.open-in-view的应用在启动的时候会有一个警告(WARN)信息. 然而这默认是友好的(friendly default), 能帮助排除你没有清楚的意识到对于你来说意味着什么. 这个信息确保你了解数据查询可能会在渲染视图期间执行. 如果确定没问题的话, 可以显示的配置这个属性来禁用这个警告信息.

JPA 和 Spring Data

在 Spring Boot 1.x, 一些开发者继承HibernateJpaAutoConfiguration来提供应用于自动配置的(auto-configured)EntityManagerFactory自定义特性, 为了防止这个错误的使用, 从Spring Boot开始不能在继承这个类.

为了支持这个应用案例, 可以定义一个HibernatePropertiesCustomizer bean来控制Hibernate属性, 包含在context注册Hibernate拦截器声明的能力 

Flyway

Flyway配置键被移动到spring命名空间(即spring.flyway)中

升级到Spring Boot 2将把Flyway从3.x升级到5.x。为确保模式升级顺利进行,请按照以下说明操作:

  • 首先将你的1.5.x Spring Boot应用程序升级到Flyway 4(在编写本文时为4.2.0),请参阅Maven及Gradle的说明

  • 一旦你的架构升级到了Flyway 4,升级到Spring Boot 2并再次运行迁移以将你的应用程序移植到Flyway 5

Liquibase

Liquibase配置键被迁移到spring命名空间(即spring.liquibase)

数据库初始化

基本数据源(DataSource)的初始化目前仅对嵌入式数据源启用,并将在你使用生产数据库时关闭。新的spring.datasource.initialization-mode(替代spring.datasource.initialize)提供了更多的控制。

create-drop更新了默认处理策略

只有在未使用任何模式管理器(如Liquibase或Flyway)时,spring.jpa.hibernate.ddl-auto属性才会默认使用嵌入式数据库进行create-drop操作。一旦检测到模式管理器,默认行为将变有为无。

应用NoSQL技术

Redis

当你使用spring-boot-starter-redis的时候,Lettuce现已取代Jedis作为Redis驱动。当你使用更好级别的Spring数据结构时,你会发现变化时清晰的。我们仍然支持Jedis,并且你可以任意切换依赖机制,通过排除io.lettuce:lettuce-core和添加redis.clients.jedis的方式。

Elasticsearch

Elasticsearch已经被升级到了5.4+版本。与 Elastic宣布:嵌入式的Elasticsearch不再支持 保持一致,NodeClient的自动配置已经被移除。TransportClient可以使用spring.data.elasticsearch.cluster-nodes来自动配置,以提供用来连接的一个或多个节点。

Caching 缓存

针对缓存的专用Hazelcast自动配置

它不再能够自动配置常规的HazelcastInstance和用于缓存的专用HazelcastInstance。因此,spring.cache.hazelcast.config属性不再是可用的。

Batch 批处理

在启动时执行批处理作业的CommandLineRunner的优先级是0。

测试

Mockito 1.x

Mockito 1.x不再支持@MockBean和@SpyBean。如果你没有使用spring-boot-starter-test来管理依赖关系,则应升级到Mockito 2.x.

Spring Boot Actuator

Spring Boot 2 给 actuator 带来了重要的变化,(包括)内部和面向用户的,请查阅参考指南的更新部分和新 actuator API 文档:

https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/actuator-api/html

你应该期待编程模型、配置键和某些端点的响应格式会发生变化。Actuator 现在本地支持 Spring MVC,Spring WebFlux 和 Jersey。

Build

Actuator的代码被分成两个模块:现有的spring-boot-actuator和一个新的spring-boot-actuator-autoconfigure。如果你正在使用它的原始模块(spring-boot-actuator)导入actuator,请考虑使用spring-boot-starter-actuator替代。

配置键结构

端点的基础结构键已被协调:

如何将项目迁移至 Spring Boot 2.0 ?        

Base path 基路径

所有终端已默认移至/actuator中。

我们修改了management.server.servlet.context-path的含义:它现在是对server.servlet.context-path的终端管理的等价替代(仅在设置了management.server.port时才有效)。另外,你还可以使用新的单独的属性management.endpoints.web.base-path来设置管理终端的基路径。

例如,如果你已经设置了management.server.servlet.context-path=/management和management.endpoints.web.base-path=/application,则可以通过以下路径访问运行状况良好的终端:/management/application/health。

如果要恢复1.x版本的行为(即拥有/health而不是/actuator/health),请设置以下属性:

 
   
   
 
management.endpoints.web.base-path=/

Audit event API 的变化

AuditEventRepository 现在是一个带有所有可选参数的单独的方法。

端点

通过 HTTP 实现一个 actuator 端点,它需要被启用并公开。默认:

  • 只有/health 和 /info 端点被公开,不管 Spring Security 是否存在并且配置于你的程序中。

  • 所有端点启用,除了 /shutdown 。

你可以公开所有的端点,如下:

 
   
   
 
management.endpoints.web.exposure.include=*

你可以显式地启用 /shutdown 端点:

 
   
   
 
management.endpoint.shutdown.enabled=true

公开除 env 端点之外的所有(已启用的) web 端点:

 
   
   
 
management.endpoints.web.exposure.include=*management.endpoints.web.exposure.exclude=env

端点属性的变化如下:

  • endpoints.<id>.enabled 被移到 management.endpoint.<id>.enabled
  • endpoints.<id>.id 不能替换(端点的 id 不再可配置)

  • endpoints.<id>.sensitive 不能替换(详见 Actuator Security )

  • endpoints.<id>.path 被移到 management.endpoints.web.path-mapping.<id>                          

终端格式

"/actuator/mappings" Actuator Endpoint的检视

JSON格式现已更改为适当地包含有关上下文层次结构、多个DispatcherServlet、已部署的Servlet和Servlet过滤器的信息。有关更多详细信息请参考#9979:
https://github.com/spring-projects/spring-boot/issues/9979#issuecomment-357930821
Actuator API文档的相关部分提供了一个示例文档。

"/actuator/httptrace" Actuator Endpoint的检视

response的结构已被细化,以反映终端聚焦跟踪HTTP请求-响应的交互。有关 终端及其response结构的更多细节可在Actuator API文档的相关部分找到。
迁移自定义端点
如果你有自定义的 actuator 端点,请查阅专门的博客帖子:
https://spring.io/blog/2017/08/22/introducing-actuator-endpoints-in-spring-boot-2-0
团队已经写了一个 wiki 页面描述如何迁移现有的 actuator 端点到新的基础结构中。

度量标准

Spring Boot 自己的度量标准已经被支持所取代,包括用于 Micrometer 和维度指标的 auto-configuration 。

配置 Micrometer

如果你的 Spring Boot 2.0 程序已经依赖于 Actuator,则 Micrometer 已在此处并自动配置。如果你希望将度量值导出到像 Prometheus、Atlas 或者 Datadog 这样的外部注册表中,Micrometer 为许多注册中心提供了依赖关系;你可以通过 spring.metrics.* 属性来配置你的程序以导出到特定的注册表中。
有关更多信息,请查看关于 Spring Boot 2.0 的 Micrometer 文档。           

迁移自定义Counters/Gauges (计数器/标尺)

作为在你的应用程序代码中插入CounterService或GaugeService实例的替代,你可以通过以下方式创建各种指标:
  • 插入一个MeterRegistry并调用它的方法
  • 直接调用像Counter featureCounter = Metrics.counter("feature");一样的静态方法
千分尺带来许多有趣的功能 - 请查看“千分尺背后的核心概念”以及Spring Boot集成的细节:
http://micrometer.io/docs/concepts | https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle#production-ready-metrics

Spring Boot 1.5支持

你可以使用Micrometer Legacy支持,将相同metrics基础架构中的现存Spring Boot 1.5应用程序插入。
开发者工具
热拔插(Hot swapping)
随着Spring Loaded项目被阁置,它在Spring Boot中的支持已经被移除。我们建议使用Devtools替代。

隧道Devtools远程调试

对通过HTTP进行隧道远程调试的支持已经从Devtools中删除。

已删除的功能

以下功能不再可用:
  • CRaSH支持
  • Spring Mobile的自动配置和依赖管理
  • Spring Social的自动配置和依赖管理,请查阅Spring Social项目了解更多细节
  • commons-digester的依赖管理

依赖版本

以下库的最低支持版本已经更改:
Elasticsearch 5.6
Gradle 4
Hibernate 5.2
Jetty 9.4
Spring Framework 5
Spring Security 5
Tomcat 8.5
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。 本文由Web项目聚集地进行整理、排版发布,转载请著名。    

我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

如果喜欢本篇文章,欢迎 转发、点赞 。关注订阅号「Web项目聚集地」,回复「全栈」即可获取 2019 年最新 Java、Python、前端学习视频资源。

推荐阅读
1.  
2. 
3. 
4. 
5.  
6.  
7.  
8. 



喜欢文章,点个在看 ↓ 

以上是关于如何将项目迁移至 Spring Boot 2.0 ?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Spring Boot 项目迁移到旧 Spring MVC 项目。面临的问题,如何在遗留 Spring MVC 项目中读取 application.properties 文件

如何将默认过期的 RedisCacheManager 迁移到 Spring Data Redis 2.0?

如何在 Spring Boot 2.0 上将默认 hikari cp 替换为 tomcat 池

迁移到 Spring Boot 2.2.0 @JsonIgnore 不起作用

Spring Boot 2.0:Spring Boot 如何解决项目启动时初始化资源

Spring Boot 2.0:Spring Boot 如何解决项目启动时初始化资源