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

# 概要

Spring Boot 2.1の開発が進んでいます。GitHubのマイルストーンはM1,M2,M3,M4,RC1が作成されていて、2018年7月30日にM1が[リリース] (https://spring.io/blog/2018/07/30/spring-boot-2-1-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

```bat
> 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

* [Spring Boot 2.1 Release Notes] (https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1-Release-Notes)
* [Spring Boot 2.1.0] (https://spring.io/blog/2018/10/30/spring-boot-2-1-0)

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

# Spring Boot 2.1.0 RC1

* [Spring Boot 2.1.0 RC1 Release Notes] (https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1.0-RC1-Release-Notes)
* [2.1.0.RC1 Milestone] (https://github.com/spring-projects/spring-boot/milestone/107?closed=1)
* [Spring Boot 2.1.0 RC1 available now] (https://spring.io/blog/2018/10/17/spring-boot-2-1-0-rc1-available-now)

## [Thymeleaf 3.0.10 configuration] (https://github.com/spring-projects/spring-boot/pull/14849)

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

```properties
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.

```properties
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] (https://github.com/spring-projects/spring-boot/issues/14806)

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

[Thymeleaf Extras Springsecurity5] (https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity5)

## [Add support for customizing Flyway's configuration] (https://github.com/spring-projects/spring-boot/issues/14786)

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

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

## [GitProperties, BuildProperties support encoding.] (https://github.com/spring-projects/spring-boot/pull/10771)

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

```text
# 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

* [Spring Boot 2.1.0 M4 Release Notes] (https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1.0-M4-Release-Notes)
* [2.1.0.M4 Milestone] (https://github.com/spring-projects/spring-boot/milestone/122?closed=1)
* [Spring Boot 2.1 M4 available now] (https://spring.io/blog/2018/09/25/spring-boot-2-1-m4-available-now)

## [Add support for Spring Data JDBC] (https://github.com/spring-projects/spring-boot/issues/14489)

[Spring Data JDBC] (https://spring.io/projects/spring-data-jdbc)をサポートする新しいスターター`spring-boot-starter-data-jdbc`がサポートされました。

[Spring Boot JDBC Starter] (https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc)

## [Support for SAP Hana Database] (https://github.com/spring-projects/spring-boot/pull/14513)

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

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

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

## [@SpringBootTest(randomPort = true) does not generate random port for actuator] (https://github.com/spring-projects/spring-boot/issues/4424)

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

```java
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
```

# Spring Boot 2.1.0 M3

* [Spring Boot 2.1.0 M3 Release Notes] (https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1.0-M3-Release-Notes)
* [2.1.0.M3 Milestone] (https://github.com/spring-projects/spring-boot/milestone/117?closed=1)
* [Spring Boot 2.1 M3 available now] (https://spring.io/blog/2018/09/13/spring-boot-2-1-m3-available-now)

## [Add support for logging groups] (https://github.com/spring-projects/spring-boot/issues/14421)

* [26.5 Log Groups] (https://docs.spring.io/spring-boot/docs/2.1.0.M3/reference/htmlsingle/#boot-features-custom-log-groups)

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

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

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

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

```text
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 |

設定例

```text
logging.level.sql = debug
```

## [Output a warning from the launch script if the application will run as root] (https://github.com/spring-projects/spring-boot/pull/10275)

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

```text
# 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] (https://github.com/spring-projects/spring-boot/pull/11077)

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

```java
@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] (https://github.com/spring-projects/spring-boot/issues/14287)

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

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

## [Throw an exception on invalid syntax in SPRING_APPLICATION_JSON] (https://github.com/spring-projects/spring-boot/pull/14251)

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

**SPRING_APPLICATION_JSON**

> [24. Externalized Configuration] (https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html)
> 
> 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] (https://github.com/spring-projects/spring-boot/issues/6514)

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

**[WebSecurityConfigurer] (https://docs.spring.io/spring-security/site/docs/5.1.0.RC2/api/org/springframework/security/config/annotation/web/WebSecurityConfigurer.html)**

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

**[WebSecurityConfigurerAdapter] (https://docs.spring.io/spring-security/site/docs/5.1.0.RC2/api/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.html)**

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

## [Deprecate 'secure' on WebMvcTest and AutoConfigureMockMvc] (https://github.com/spring-projects/spring-boot/issues/14227)

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

```java
@WebMvcTest(secure = false)
```

## [Support WebExceptionHandler in @WebFluxTest] (https://github.com/spring-projects/spring-boot/issues/13627)

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

**[WebExceptionHandler] (https://docs.spring.io/spring/docs/5.1.0.RC3/javadoc-api/org/springframework/web/server/WebExceptionHandler.html)**

```java
public interface WebExceptionHandler
```

# Spring Boot 2.1.0 M2

* [Spring Boot 2.1.0 M2 Release Notes] (https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1.0-M2-Release-Notes)
* [2.1.0.M2 Milestone] (https://github.com/spring-projects/spring-boot/milestone/101?closed=1)
* [Spring Boot 2.1 M2 available now] (https://spring.io/blog/2018/08/21/spring-boot-2-1-m2-available-now)

## [Support FormContentFilter, as HttpPutFormContentFilter is now deprecated] (https://github.com/spring-projects/spring-boot/issues/13363)

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

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

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

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

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

## [adding property to disable HiddenHttpMethodFilter] (https://github.com/spring-projects/spring-boot/pull/14030)

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

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

## [Fine-tune and review logging output] (https://github.com/spring-projects/spring-boot/issues/13511)

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

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

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

```properties
spring.http.log-request-details=false
```

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

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

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

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

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

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

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

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

* [Reconsider DEBUG web logs enabled by default when devtools is present] (https://github.com/spring-projects/spring-boot/issues/14575)

## [Allow Spring Data JPA's bootstrap mode to be configured via the environment] (https://github.com/spring-projects/spring-boot/issues/13833)

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

* default
* deferred
* lazy

```properties
spring.data.jpa.repositories.boostrap-mode=default # Bootstrap mode for JPA repositories.
```

**default**

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

// ...省略...

```

**deferred**

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

```text
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リポジトリが利用されるタイミングで初期化されます。

```text
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] (https://github.com/spring-projects/spring-boot/issues/1397)

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

```properties
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] (https://github.com/spring-projects/spring-boot/pull/14052)

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

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

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

```java
@ActiveProfiles("test")
@DataJpaTest
```

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

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

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

* [@JdbcTests] (https://github.com/spring-projects/spring-boot/pull/14052/commits/0f614b9ef478346491c9f1e729dd8cf6bba456de)
* [@DataJpaTest] (https://github.com/spring-projects/spring-boot/pull/14052/commits/3d22329b3ff2439ea3e1653fcfd9639cbe46df5d)
* [@RestClientTest] (https://github.com/spring-projects/spring-boot/pull/14052/commits/42887c921ea5f729606c10dfba5cc73acdbf8fde)
* [@WebMvcTest] (https://github.com/spring-projects/spring-boot/pull/14052/commits/67f6affff801d070131376f04ea2721fbee085fc)
* [@WebFluxTest] (https://github.com/spring-projects/spring-boot/pull/14052/commits/baa7b64b361104b9710af71977e080a36380ae34)
* [@DataLdapTest] (https://github.com/spring-projects/spring-boot/pull/14052/commits/e571dc4c16b183c01af3da6885478b635a14c13b)
* [@DataMongoTest] (https://github.com/spring-projects/spring-boot/pull/14052/commits/86ab0795ff392a19c004c72e54ae9eaa064a91cf)
* [@DataNeo4jTest] (https://github.com/spring-projects/spring-boot/pull/14052/commits/cc63f691b588806198786b40e2a1cb035c560732)
* [@DataRedisTest] (https://github.com/spring-projects/spring-boot/pull/14052/commits/a4bb93d70d6a0d48dc8858b0c07fe92da3944205)
* [@JooqTest] (https://github.com/spring-projects/spring-boot/pull/14052/commits/30884be8fa76c86acc251337c469a4579765171e)
* [@JsonTest] (https://github.com/spring-projects/spring-boot/pull/14052/commits/5f7ff65cad9f7a7115be62a1b870c6b65ea67f3f)

## [Provide a rich type and converter to be used by properties that configure a number of bytes] (https://github.com/spring-projects/spring-boot/issues/13974)

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

* `B` for bytes
* `KB` for kilobytes
* `MB` for megabytes
* `GB` for gigabytes
* `TB` for terabytes

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

![x.png](https://qiita-image-store.s3.amazonaws.com/0/22772/107b63e9-4ef0-8852-bdc5-62789e72363f.png)

## [Auto-configure a sensible TaskExecutor] (https://github.com/spring-projects/spring-boot/issues/1563)

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

```properties
# 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] (https://github.com/spring-projects/spring-boot/pull/13966)

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

```properties
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] (https://github.com/spring-projects/spring-boot/issues/14114)

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

> [changelog] (https://projectlombok.org/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

* [Spring Boot 2.1.0 M1 Release Notes] (https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1.0-M1-Release-Notes)
* [2.1.0.M1 Milestone] (https://github.com/spring-projects/spring-boot/milestone/99?closed=1)
* [Spring Boot 2.1 M1] (https://spring.io/blog/2018/07/30/spring-boot-2-1-m1)

## [PR #9714: JVM arguments and options] (https://github.com/spring-projects/spring-boot/pull/10741)

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

```xml
<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>
```

```java
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)] (https://github.com/spring-projects/spring-boot/issues/11725)

JPA 2.2をサポートしたので、クエリ結果をStreamとして受け取ることができます。
なお、このIssueの[コメント-359568785] (https://github.com/spring-projects/spring-boot/issues/11725#issuecomment-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] (https://javaee.github.io/javaee-spec/javadocs/javax/persistence/Query.html#getResultStream--)**

```text:sigunature
default Stream getResultStream()
```

**[TypedQuery.getResultStream] (https://javaee.github.io/javaee-spec/javadocs/javax/persistence/TypedQuery.html#getResultStream--)**

```text:sigunature
default Stream<X> getResultStream()
```

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

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

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

```java:org.hibernate.query.Query&lt;R&gt;
Stream<R> stream();

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


## [Support AND operator in yml profile matching] (https://github.com/spring-projects/spring-boot/issues/12469)

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

```yaml: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を使用します。

```text
> 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] (https://jira.spring.io/browse/SPR-12458)

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

```java
public interface AppCondition {
  String name();
}
```

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

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

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

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

## [Set up environment variables using the Maven plugin] (https://github.com/spring-projects/spring-boot/pull/12800)

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

```xml
<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>
```

```java
System.out.println("ENV1: [" + environment.getProperty("ENV1") + "] ENV2: [" + environment.getProperty("ENV2") + "]");
// → ENV1: [value1] ENV2: [value2]
```

## [Add support for PageableHandlerMethodArgumentResolver in WebMvcTest] (https://github.com/spring-projects/spring-boot/pull/13066)

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

### サンプルコード

**テスト対象**

```java
@RestController
public class EchoController {

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

}
```

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

↓ response

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

**テストコード**

```java
@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] (https://github.com/spring-projects/spring-boot/pull/13355)

[RestTemplateBuilder (Spring Boot Docs 2.1.0.M1 API)] (https://docs.spring.io/spring-boot/docs/2.1.0.M1/api/org/springframework/boot/web/client/RestTemplateBuilder.html)

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

**既存のメソッドはDeprecated**

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

```text:signature
@Deprecated
public RestTemplateBuilder setConnectTimeout(int connectTimeout)
```

> Sets the connection timeout in milliseconds on the underlying ClientHttpRequestFactory.

```text:signature
@Deprecated
public RestTemplateBuilder setReadTimeout(int readTimeout)
```

> Sets the read timeout in milliseconds on the underlying ClientHttpRequestFactory.

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

Duration型を受け取ります。

```text:signature
public RestTemplateBuilder setConnectTimeout(Duration connectTimeout)
```

```text:signature
public RestTemplateBuilder setReadTimeout(Duration readTimeout)
```

### サンプルコード

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

## [Support profile expression in Logback's <springProfile>] (https://github.com/spring-projects/spring-boot/issues/13496)

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

```xml
<?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)] (https://github.com/spring-projects/spring-boot/issues/13739)

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

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

  @Test
  public void contextLoads() {
  }

}
```

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

```java
@SpringBootTest
public class ApplicationTests {

  @Test
  public void contextLoads() {
  }

}
```

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

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

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

* JsonTest

# 補足