SpringBoot v2.7以降に使えなくなるDataSourcePropertiesのメソッドをリファクタリングしておいた

エンジニアをしていると、FWやライブラリのバージョン変更により、今まで使えていたコードが使えなくなるという事象に頭を悩まされることは多々あります:frowning2:

今回、SpringBootのバージョンアップを機に、使えなくなるコードを発見したので、あらかじめ対応した覚書をしておこうと思います！

## 環境
- Java11
- SpringBoot v2.6.14
- Intellij IDEA

## 現行コード
```properties:application.properties
spring.datasource.db1.url=jdbc:h2:mem:testMysqldb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;Mode=MySQL
spring.datasource.db1.driver-class-name=org.h2.Driver
spring.datasource.db1.username=sa
spring.datasource.db1.password=
spring.datasource.db1.schema=classpath:schema.sql
spring.datasource.db1.data=classpath:data.sql
spring.datasource.db1.hikari.minimumIdle=3
spring.datasource.db1.hikari.maximumPoolSize=6
```
```java:DataSourceDb1Config
import java.util.Collection;
import java.util.Optional;
import java.util.stream.Stream;
import javax.sql.DataSource;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;

/**
 * DB1データソース接続設定クラス
 */
@Configuration
public class DataSourceDb1Config {

  /**
   * DBのデータソースプロパティを返却する
   *
   * @return DBのデータソースプロパティ
   */
  @Bean(name = "datasourceProperties")
  @ConfigurationProperties(prefix = "spring.datasource.db1")
  public DataSourceProperties datasourceProperties() {
    return new DataSourceProperties();
  }

  /**
   * DBのデータソースを返却する
   *
   * @param datasourceProperties DBのデータソースプロパティv
   * @return データソース
   */
  @Bean(name = "dataSource")
  @ConfigurationProperties(prefix = "spring.datasource.db1.hikari")
  public DataSource dataSource(
      @Qualifier("datasourceProperties") DataSourceProperties datasourceProperties) {
    return datasourceProperties.initializeDataSourceBuilder().build();
  }

  /**
   * DataSourceInitializerを返却する
   *
   * @param datasourceProperties DBのdatasourceProperties
   * @param dataSource           DBのdataSource
   * @return DBのdataSourceInitializer
   */
  @Bean(name = "dataSourceInitializer")
  public DataSourceInitializer dataSourceInitializer(
      @Qualifier("datasourceProperties") DataSourceProperties datasourceProperties,
      @Qualifier("dataSource") DataSource dataSource) {
    ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
    ResourceLoader resourceLoader = new DefaultResourceLoader();
    Stream
        .concat(
            Optional.ofNullable(datasourceProperties.getSchema()).stream()
                .flatMap(Collection::stream),
            Optional.ofNullable(datasourceProperties.getData()).stream()
                .flatMap(Collection::stream))
        .map(resourceLoader::getResource).forEach(populator::addScript);

    DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
    dataSourceInitializer.setDataSource(dataSource);
    dataSourceInitializer.setDatabasePopulator(populator);
    return dataSourceInitializer;
  }
}
```
IDEで見ると、下記のような表示になっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630308/bae2047b-048f-0847-22ff-36c955577293.png)

取り消し線があるところにカーソンを合わせてホバーすると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630308/209a8521-0215-81eb-fc98-d98db2182632.png)

なんと非推奨になっているではありませんか。。

よくよく調べてみると、SpringBoot2.5.0から、下記2つが使用すべきではないコードとして一覧に上がっていました。

>org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.getSchema()
org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.getData()

https://docs.spring.io/spring-boot/docs/2.5.0/api/deprecated-list.html

さらに、**SpringBoot2.7.0以降にバージョンアップすると、完全に使えなくなるということも判明しました。**

今後確実にSpringBoot2.7.0以降にバージョンアップするので、あらかじめ対応しておこうと思います！

## どう変更するか
| 対象 | 変更前 | 変更後 |
|:-:|:-:|:-:|
| application.properties  | spring.datasource.db1.schema  | spring.datasource.db1.schema-locations  |
| application.properties  | spring.datasource.db1.data | spring.datasource.db1.data-locations  |
| DataSourceDb1Config#dataSourceInitializer  | DatasourceProperties.getSchema() | SqlInitializationProperties.getSchemaLocations()  |
| DataSourceDb1Config#dataSourceInitializer  | DatasourceProperties.getData()  | SqlInitializationProperties.getDataLocations()  |
| DataSourceDb1Config#sqlInitializationProperties  | -  | 追加  |

https://spring.pleiades.io/spring-boot/docs/2.5.1/api/org/springframework/boot/autoconfigure/sql/init/SqlInitializationProperties.html

## 新コード
```properties:application.properties
spring.datasource.db1.url=jdbc:h2:mem:testMysqldb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;Mode=MySQL
spring.datasource.db1.driver-class-name=org.h2.Driver
spring.datasource.db1.username=sa
spring.datasource.db1.password=
spring.datasource.db1.schema-locations=classpath:schema.sql
spring.datasource.db1.data-locations=classpath:data.sql
spring.datasource.db1.hikari.minimumIdle=3
spring.datasource.db1.hikari.maximumPoolSize=6
```
```java:DataSourceDb1Config
import java.util.Collection;
import java.util.Optional;
import java.util.stream.Stream;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.sql.init.SqlInitializationProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;

/**
 * DB1データソース接続設定クラス
 */
@Configuration
public class DataSourceDb1Config {

  /**
   * DB初期化プロパティを返却する
   *
   * @return DB初期化プロパティ
   */
  @Bean(name = "sqlInitializationProperties")
  @ConfigurationProperties(prefix = "spring.datasource.db1")
  public SqlInitializationProperties sqlInitializationProperties() {
    return new SqlInitializationProperties();
  }

  /**
   * DBのデータソースプロパティを返却する
   *
   * @return DBのデータソースプロパティ
   */
  @Bean(name = "datasourceProperties")
  @ConfigurationProperties(prefix = "spring.datasource.db1")
  public DataSourceProperties datasourceProperties() {
    return new DataSourceProperties();
  }

  /**
   * DBのデータソースを返却する
   *
   * @param datasourceProperties DBのデータソースプロパティv
   * @return データソース
   */
  @Bean(name = "dataSource")
  @ConfigurationProperties(prefix = "spring.datasource.db1.hikari")
  public DataSource dataSource(
      @Qualifier("datasourceProperties") DataSourceProperties datasourceProperties) {
    return datasourceProperties.initializeDataSourceBuilder().build();
  }

  /**
   * DataSourceInitializerを返却する
   *
   * @param sqlInitializationProperties DBのsqlInitializationProperties
   * @param dataSource           DBのdataSource
   * @return DBのdataSourceInitializer
   */
  @Bean(name = "dataSourceInitializer")
  public DataSourceInitializer dataSourceInitializer(
      @Qualifier("sqlInitializationProperties") SqlInitializationProperties sqlInitializationProperties,
      @Qualifier("dataSource") DataSource dataSource) {
    ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
    ResourceLoader resourceLoader = new DefaultResourceLoader();
    Stream
        .concat(
            Optional.ofNullable(sqlInitializationProperties.getSchemaLocations()).stream()
                .flatMap(Collection::stream),
            Optional.ofNullable(sqlInitializationProperties.getDataLocations()).stream()
                .flatMap(Collection::stream))
        .map(resourceLoader::getResource).forEach(populator::addScript);

    DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
    dataSourceInitializer.setDataSource(dataSource);
    dataSourceInitializer.setDatabasePopulator(populator);
    return dataSourceInitializer;
  }
}

```

以上です！