Help us understand the problem. What is going on with this article?

Spring Boot 2.1.0で追加・変更された機能

More than 1 year has passed since last update.

概要

Spring Boot 2.1の開発が進んでいます。GitHubのマイルストーンはM1,M2,M3,M4,RC1が作成されていて、2018年7月30日にM1がリリースされました。
この記事ではそれぞれのマイルストーンで対応されたIssueで機能の追加や変更されたものから、個人的に気になったものをピックアップしてまとめました。

環境

  • Windows 10 Professional
  • OpenJDK 11 (build 11+28)
  • Spring Boot 2.1.0 RELEASE
  • MySQL CE 8.0.12
  • JUnit 5.2.0
  • Maven 3.5.4
> java -version
openjdk version "11" 2018-09-25
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)

Spring Boot 2.1.0 RELEASE

2018年10月30日にSpring Boot 2.1.0がリリースされました。

Spring Boot 2.1.0 RC1

Thymeleaf 3.0.10 configuration

Thymeleafの設定パラメータが2つ追加されました。

spring.thymeleaf.render-hidden-markers-before-checkboxes=false

Whether hidden form inputs acting as markers for checkboxes should be rendered before the checkbox element itself.

spring.thymeleaf.servlet.produce-partial-output-while-processing=true

Whether Thymeleaf should start writing partial output as soon as possible or buffer until template processing is finished.

Switch from thymeleaf-extras-springsecurity4 to thymeleaf-extras-springsecurity5

ThymeleafとSpring Security 5を統合するアーティファクトthymeleaf-extras-springsecurity5が追加されました。

Thymeleaf Extras Springsecurity5

Add support for customizing Flyway's configuration

FlywayをカスタマイズできるFlywayConfigurationCustomizerが追加されました。

@Bean
public FlywayConfigurationCustomizer customizer() {
  return (configuration) -> configuration.connectRetries(5).ignorePendingMigrations(true);
}

GitProperties, BuildProperties support encoding.

build-info.propertiesgit.propertiesの出力にファイルエンコードを指定できるようになりました。

# PROJECT INFORMATION ({sc-spring-boot-autoconfigure}/info/ProjectInfoProperties.{sc-ext}[ProjectInfoProperties])
spring.info.build.encoding=UTF-8 # File encoding.
spring.info.git.encoding=UTF-8 # File encoding.

Spring Boot 2.1.0 M4

Add support for Spring Data JDBC

Spring Data JDBCをサポートする新しいスターターspring-boot-starter-data-jdbcがサポートされました。

Spring Boot JDBC Starter

Support for SAP Hana Database

インメモリーデータベースのSAP Hana Database (HDB)がサポートされました。

DatabaseDriver
SAP("HDB", "com.sap.db.jdbc.Driver", "com.sap.db.jdbcext.XADataSourceSAP", "SELECT 1 FROM DUMMY"),

SAP HANA インメモリーデータベース

SAP HANA の中心にあるのは、リレーショナルデータベース管理システム(RDBMS)です。単一のインメモリーデータベースに OLAP と OLTP の処理を結合し、ディスクのボトルネックを解消し、画期的な性能を提供します。この ACID 準拠のインメモリー列指向データベースは、圧縮データを格納し、マルチプロセッサーコア間の並列処理を提供し、単一命令複数データ(SIMD)コマンドをサポートします。

@SpringBootTest(randomPort = true) does not generate random port for actuator

SpringBootTest時にserver.portとは別にmanagement.server.port用のランダムなポートを生成できるようになりました。

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)

Spring Boot 2.1.0 M3

Add support for logging groups

関連するロガーをロググループにまとめて設定できるようになりました。

下記のようにまとめたいロガーをロググループに定義します。{ロググループ名}は任意の文字列です。

logging.group.{ロググループ名} = {ロガー1}, {ロガー2}, {ロガーn}

デバッグレベルを{ロググループ名}に設定します。

logging.level.{ロググループ名} = debug

Spring Bootの事前定義されたロググループ

webとsqlという2つのロググループが定義済みです。

ロググループ ロガー
web org.springframework.core.codec, org.springframework.http, org.springframework.web
sql org.springframework.jdbc.core, org.hibernate.SQL

設定例

logging.level.sql = debug

Output a warning from the launch script if the application will run as root

Spring Bootアプリケーションをrootユーザーで実行すると、起動スクリプト(launch.script)が警告を出力するようになりました。

# Issue a warning if the application will run as root
[[ $(id -u ${run_user}) == "0" ]] && { echoYellow "Application is running as root (UID 0). This is considered insecure."; }

Consider @Primary annotation when using @MockBean, make @MockBean/@SpyBean behave consistently

@MockBean / @SpyBeanを付けたフィールドに、@Primaryを付けたオブジェクトが優先して注入されるようになりました。

@SpringBootTest
public class ExampleServiceTests {

  @SpyBean(classes = {ExampleService.class})
  ExampleService service;

  @Test
  public void test() {
    System.out.println(service.getName());
    // example2
  }

  interface ExampleService {
    String getName();
  }

  static class ExampleServiceImpl implements ExampleService {
    private String name;

    public ExampleServiceImpl(String name) {
      this.name = name;
    }

    @Override
    public String getName() {
      return this.name;
    }
  }

  @Configuration
  static class ExampleConfigure {

    @Bean
    public ExampleService example1() {
      return new ExampleServiceImpl("example1");
    }

    @Bean
    @Primary
    public ExampleService example2() {
      return new ExampleServiceImpl("example2");
    }

  }

}

Provide the necessary dependencies in the JPA starter for it to work on Java 9 and later

Java 9以降でJPA (Hibernate ORM)を利用する場合は下記のようにjaxb-apiをプロジェクトの依存関係に含める必要がありましたが、これからはspring-boot-starter-data-jpajaxb-apiの依存関係が追加されたので明示的な記述は不要です。

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
</dependency>

Throw an exception on invalid syntax in SPRING_APPLICATION_JSON

SPRING_APPLICATION_JSONにパースの出来ないJson文字列を指定した場合、今まではwarnレベルのログを出力するだけでしたが、これからはJsonParseExceptionをスローするようになりました。

SPRING_APPLICATION_JSON

24. Externalized Configuration

The SPRING_APPLICATION_JSON properties can be supplied on the command line with an environment variable.
For example, you could use the following line in a UN*X shell:
$ SPRING_APPLICATION_JSON='{"acme":{"name":"test"}}' java -jar myapp.jar

Include web security configuration classes when @WebMvcTest.secure is true

WebSecurityConfigurerインターフェースを実装したセキュリティ設定クラスが@WebMvcTestで反映されるようになりました。
いままでは@WebMvcTestでのテストでセキュリティ設定を反映したテスト(認証・認可、アクセス制御など)を行うには、別途セキュリティ設定をimportしなければなりませんでした。

WebSecurityConfigurer

public interface WebSecurityConfigurer<T extends SecurityBuilder<javax.servlet.Filter>> extends SecurityConfigurer<javax.servlet.Filter,T>

WebSecurityConfigurerAdapter

@Order(value=100)
public abstract class WebSecurityConfigurerAdapter extends java.lang.Object implements WebSecurityConfigurer<WebSecurity>

Deprecate 'secure' on WebMvcTest and AutoConfigureMockMvc

@WebMvcTestsecureメソッドが廃止予定(Deprecated)になりました。
いままでは@WebMvcTestでのテストでセキュリティ設定を無視したい場合にfalseにすることがありました。

@WebMvcTest(secure = false)

Support WebExceptionHandler in @WebFluxTest

WebExceptionHandlerインターフェースを実装した例外ハンドラクラスが@WebFluxTestをサポートするようになりました。

WebExceptionHandler

public interface WebExceptionHandler

Spring Boot 2.1.0 M2

Support FormContentFilter, as HttpPutFormContentFilter is now deprecated

HttpPutFormContentFilterの利用が非推奨になり、代わりにFormContentFilterをサポートするようになりました。

プロパティ名も変わりました。

spring.mvc.formcontent.putfilter.enabled=true # Whether to enable Spring's HttpPutFormContentFilter.

これからは以下のプロパティで設定します。

spring.mvc.formcontent.filter.enabled=true # Whether to enable Spring's FormContentFilter.

adding property to disable HiddenHttpMethodFilter

HiddenHttpMethodFilterを無効にするプロパティが追加されました。

spring.mvc.hiddenmethod.filter.enabled=true # Whether to enable Spring's HiddenHttpMethodFilter.

Fine-tune and review logging output

WebMvc、WebFluxのログ出力を調整するプロパティが追加されました。

# INSIGHTS
spring.insights.web.log-request-details=false # Whether logging of (potentially sensitive) request details at DEBUG and TRACE level is allowed.

M3でプロパティ名が変更されました

spring.http.log-request-details=false

spring-boot-devtoolsが有効な状態で、このパラメータをtrueに設定するとpostパラメータがログに出力されるようになります。

たとえば下記のようなPOSTリクエストを送ると

curl -v -d "message=test" -d "param1=123" -d "param2=abc" -X POST "http://localhost:9000/app/echo3"

ログに下記の内容が出力されます。

POST "/app/echo3", parameters={message:[test], param1:[123], param2:[abc]}

FALSE(デフォルト)の場合は下記のようにマスクされて出力されます。

POST "/app/echo3", parameters={masked}

M4でプロパティが削除されました

Allow Spring Data JPA's bootstrap mode to be configured via the environment

JPAリポジトリの初期化タイミングを制御するプロパティが追加されました。選択できるタイミングは下記の3種類でdefaultが従来の設定です。

  • default
  • deferred
  • lazy
spring.data.jpa.repositories.boostrap-mode=default # Bootstrap mode for JPA repositories.

default

Bootstrapping Spring Data repositories in DEFAULT mode.
Finished Spring Data repository scanning in 87ms. Found 2 repository interfaces.

// ...省略...

deferred

JPAリポジトリの初期化タイミングを遅らせます。

Bootstrapping Spring Data repositories in DEFERRED mode.
Finished Spring Data repository scanning in 73ms. Found 2 repository interfaces.

// ...省略...

Triggering deferred initialization of Spring Data repositories…

// ...省略...

Spring Data repositories initialized!

// ...省略...

lazy

JPAリポジトリが利用されるタイミングで初期化されます。

Bootstrapping Spring Data repositories in LAZY mode.
Finished Spring Data repository scanning in 98ms. Found 2 repository interfaces.

Provide properties to set the number of threads of spring TaskScheduler

TaskSchedulerのスレッド数をプロパティで設定できるようになりました。

spring.task.scheduling.pool.size=1 # Maximum allowed number of threads.
spring.task.scheduling.thread-name-prefix=scheduling- # Prefix to use for the names of newly created threads.

Allow properties to be configured using slice test annotations

@SpringBootTestでは下記のようにプロファイルを指定することができましたが、他のテスト用アノテーション(JdbcTestsDataJpaTestなど)でも同様にプロファイルの指定ができるようになりました。

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
              , properties = "spring.active.profiles=test")

いままでは下記のように書く必要がありましたが

@ActiveProfiles("test")
@DataJpaTest

これからは以下のように書くことができます。

@DataJpaTest("spring.profiles.active=test")

対応されたアノテーションは以下の通りです。

Provide a rich type and converter to be used by properties that configure a number of bytes

バイト数を指定するプロパティに10MB1GBのような指定ができるようになりました。
指定できる単位は下記の通りです。

  • B for bytes
  • KB for kilobytes
  • MB for megabytes
  • GB for gigabytes
  • TB for terabytes

ちなみにIntelliJ IDEAでプロパティ名を補完するときに表示される型がDataSizeの場合は、これらの表記で値を記述できます。

x.png

Auto-configure a sensible TaskExecutor

TaskExecutorがAuto Configurationをサポートしました。以下のプロパティで調整することができます。

# TASK EXECUTION
spring.task.pool.allow-core-thread-timeout=true # Whether core threads are allowed to time out. This enables dynamic growing and shrinking of the pool.
spring.task.pool.core-size=8 # Core number of threads.
spring.task.pool.keep-alive=60s # Time limit for which threads may remain idle before being terminated.
spring.task.pool.max-size= # Maximum allowed number of threads. If tasks are filling up the queue, the pool can expand up to that size to accommodate the load. Ignored if the queue is unbounded.
spring.task.pool.queue-capacity= # Queue capacity. A unbounded capacity does not increase the pool and therefore ignores the "max-size" parameter.
spring.task.thread-name-prefix=executor- # Prefix to use for the names of newly created threads.

Make max swallow size easily configurable

TomcatのmaxSwallowSizeプロパティをserver.tomcat.max-swallow-sizeプロパティで設定できるようになりました。

server.tomcat.max-swallow-size=2MB # Maximum amount of request body bytes to swallow.

Tomcat 9のデフォルトは、下記に引用したとおり2,097,152 bytes (2MB)です。

https://tomcat.apache.org/tomcat-9.0-doc/config/http.html

The maximum number of request body bytes (excluding transfer encoding overhead) that will be swallowed by Tomcat for an aborted upload. An aborted upload is when Tomcat knows that the request body is going to be ignored but the client still sends it. If Tomcat does not swallow the body the client is unlikely to see the response. If not specified the default of 2097152 (2 megabytes) will be used. A value of less than zero indicates that no limit should be enforced.

Upgrade to Lombok 1.18.2

Lombok 1.16.xからLombok.1.18.2へアップグレードしました。
Lombok 1.18.xの破壊的変更点(BREAKING CHANGE)として、デフォルトでプライベートな引数無しのコンストラクタを生成しなくなりました。

changelog

BREAKING CHANGE: The in 1.16.22 introduced configuration key lombok.noArgsConstructor.extraPrivate is now false by default. Issue #1708

Spring Boot 2.1.0 M1

PR #9714: JVM arguments and options

Spring Boot Maven Pluginからアプリケーションを実行する際に、システムプロパティをsystemPropertyVariablesで設定することができます。
(なお、jvmArgumentsは以前から利用可能です。)

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration>
        <jvmArguments>-Dprop1="value1" -Dprop2="value2"</jvmArguments>
        <systemPropertyVariables>
          <prop3>value3</prop3>
          <prop4>value4</prop4>
        </systemPropertyVariables>
      </configuration>
    </plugin>
  </plugins>
</build>
System.out.println("prop1:[" + System.getProperty("prop1") + "] prop2:[" + System.getProperty("prop2") + "]");
// → prop1:[value1] prop2:[value2]
System.out.println("prop3:[" + System.getProperty("prop3") + "] prop4:[" + System.getProperty("prop4") + "]");
// → prop3:[value3] prop4:[value4]

Support Hibernate 5.3.0 / JPA 2.2 (JDK8 Streams for pagination)

JPA 2.2をサポートしたので、クエリ結果をStreamとして受け取ることができます。
なお、このIssueのコメント-359568785にもあるように、非トランザクションではSpring Framework 5.0でサポートされているとのことです。

As for the JPA 2.2 API, that's explicitly supported in Spring Framework 5.0 already, including proper handling of result streams in non-transactional scenarios.

Query.getResultStream

sigunature
default Stream getResultStream()

TypedQuery.getResultStream

sigunature
default Stream<X> getResultStream()

また、JavaDocに記載の通りデフォルトの実装はgetResultListへの委譲なので、そのままではJPA 2.1と変わりません。

default Stream getResultStream() {
    return getResultList().stream();
}

Hibernate ORM 5.3.3では、このメソッドは以下のようにオーバーライドされています。
(stream()は、AbstractProducedQuery<R>に実装)

org.hibernate.query.Query<R>
Stream<R> stream();

default Stream<R> getResultStream() {
  return stream();
}

Support AND operator in yml profile matching

アプリケーション設定ファイル(yml)で、profile matchingにAND演算子(&)がサポートされました。

application.yml
spring:
  profiles:
    active: dev

# ...省略...

---

spring:
  profiles: dev & app1
server:
  port: 9001

---

spring:
  profiles: dev & app2
server:
  port: 9002

下記のように2つのprofileを指定して実行すると、この条件に一致するproflieの設定が適用されます。この例ではアプリケーションはport 9001を使用します。

> mvnw spring-boot:run -Dspring-boot.run.profiles=dev,app1

ちなみにprofile matchingに使用できる演算子はyamlの機能ではなく、Spring FrameworkおよびSpring Boot独自のもので、以下の演算子があります。

  • & AND
  • | OR
  • ! NOT

Support AND operator in @Profile annotation

@ProfileでもAND演算子がサポートされていますが、こちらはSpring FrameworkのIssueで5.1 RC1で解決されています。

public interface AppCondition {
  String name();
}

実行時のprofileに"dev,app1"を指定した場合に登録される

@Component
@Profile("dev & app1")
public class DevApp1 implements AppCondition {
  @Override
  public String name() {
    return "app1";
  }
}

実行時のprofileに"dev,app2"を指定した場合に登録される

@Component
@Profile("dev & app2")
public class DevApp2 implements AppCondition {
  @Override
  public String name() {
    return "app2";
  }
}

Set up environment variables using the Maven plugin

Spring Boot Maven Pluginからアプリケーションを実行する際に、環境変数をenvironmentVariablesで設定することができます。

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration>
        <environmentVariables>
          <ENV1>value1</ENV1>
          <ENV2>value2</ENV2>
        </environmentVariables>
      </configuration>
    </plugin>
  </plugins>
</build>
System.out.println("ENV1: [" + environment.getProperty("ENV1") + "] ENV2: [" + environment.getProperty("ENV2") + "]");
// → ENV1: [value1] ENV2: [value2]

Add support for PageableHandlerMethodArgumentResolver in WebMvcTest

@WebMvcTestを使ったコントローラの単体テストでPageableHandlerMethodArgumentResolverがサポートされたので、ハンドラメソッドにPageableを受け取るテストコードを以下のように書くことができます。

サンプルコード

テスト対象

@RestController
public class EchoController {

  @GetMapping(path = "page")
  public ResponseEntity<Pageable> page(Pageable page) {
    return ResponseEntity.ok(page);
  }

}
localhost:9000/page?page=0&size=20&sort=id,desc

↓ response

Page request [number: 0, size 20, sort: id: DESC]

テストコード

@WebMvcTest(EchoController.class)
public class EchoControllerTests {

  @Autowired
  private MockMvc mvc;

  @Test
  public void page() throws Exception {
    mvc.perform(get("/page")
      .param("page", "0")
      .param("size", "20")
      .param("sort", "id,desc"))
      .andExpect(status().isOk())
      .andExpect(jsonPath("$.pageNumber", is(0)))
      .andExpect(jsonPath("$.pageSize", is(20)))
      .andExpect(jsonPath("$.offset", is(0)))
      .andExpect(jsonPath("$.paged", is(true)))
      .andExpect(jsonPath("$.unpaged", is(false)))
      .andExpect(jsonPath("$.sort.sorted", is(true)))
      .andExpect(jsonPath("$.sort.unsorted", is(false)))
      .andDo(print());
  }

}

Add duration support for setConnectTimeout and setReadTimeout

RestTemplateBuilder (Spring Boot Docs 2.1.0.M1 API)

RestTemplateBuilderでタイムアウト(接続、読み取り)の指定にDuration型を指定できるようになりました。また、既存のint型でミリ秒を指定するメソッドはDeprecatedになりました。

既存のメソッドはDeprecated

いずれのメソッドも指定する値の単位はミリ秒。

signature
@Deprecated
public RestTemplateBuilder setConnectTimeout(int connectTimeout)

Sets the connection timeout in milliseconds on the underlying ClientHttpRequestFactory.

signature
@Deprecated
public RestTemplateBuilder setReadTimeout(int readTimeout)

Sets the read timeout in milliseconds on the underlying ClientHttpRequestFactory.

2.1.0 M1から追加されたメソッド

Duration型を受け取ります。

signature
public RestTemplateBuilder setConnectTimeout(Duration connectTimeout)
signature
public RestTemplateBuilder setReadTimeout(Duration readTimeout)

サンプルコード

RestTemplate restTemplate = new RestTemplateBuilder()
    .setConnectTimeout(Duration.ofSeconds(3))
    .setReadTimeout(Duration.ofSeconds(3))
    .build();

Support profile expression in Logback's

logback-spring.xmlの<springProfile>で、profile matchingにAND演算子(&)がサポートされました。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <include resource="org/springframework/boot/logging/logback/base.xml" />

  <springProfile name="dev & app1">
    <property name="logFilePath" value="./log/app1/" />
  </springProfile>

  <springProfile name="dev & app2">
    <property name="logFilePath" value="./log/app2/" />
  </springProfile>

</configuration>

Annotate @…Test annotations with @ExtendWith(SpringExtension.class)

JUnit5とSpring Bootのテスト用アノテーション(@SpringBootTest@WebMvcTestなど)を併用する場合、@ExtendWithを省略することができます。

@ExtendWith(SpringExtension.class)
@SpringBootTest
public class ApplicationTests {

  @Test
  public void contextLoads() {
  }

}

上記のコードはこのように書けます。

@SpringBootTest
public class ApplicationTests {

  @Test
  public void contextLoads() {
  }

}

併用すると省略可能なアノテーション

  • SpringBootTest
  • WebMvcTest
  • WebFluxTest
  • RestClientTest
  • DataJpaTest
  • DataRedisTest
  • DataNeo4jTest
  • DataMongoTest
  • DataLdapTest
  • JdbcTest
  • JooqTest

省略できないアノテーション

  • JsonTest

補足

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away