1. 概要

このチュートリアルでは、Springでのプロファイルの紹介に焦点を当てます。

プロファイルはフレームワークのコア機能であり、を使用すると、Beanをさまざまなプロファイルにマップできます。たとえば、 dev test prod[ X163X]。

次に、さまざまな環境でさまざまなプロファイルをアクティブ化して、必要なBeanのみをブートストラップできます。

2. Beanで@Profileを使用する

簡単に始めて、Beanを特定のプロファイルに属するようにする方法を見てみましょう。 @Profileアノテーションを使用します—Beanをその特定のプロファイルにマッピングしています; 注釈は、単に1つ(または複数)のプロファイルの名前を取ります。

基本的なシナリオを考えてみましょう。開発中にのみアクティブにする必要があり、本番環境にはデプロイしないBeanがあります。

そのBeanにdevプロファイルで注釈を付けます。これは、開発中のコンテナーにのみ存在します。 本番環境では、devは単にアクティブになりません。

@Component
@Profile("dev")
public class DevDatasourceConfig

簡単な補足として、プロファイル名の前にNOT演算子を付けることもできます(例:!dev )。これにより、プロファイルから除外できます。

この例では、コンポーネントはdevプロファイルがアクティブでない場合にのみアクティブになります。

@Component
@Profile("!dev")
public class DevDatasourceConfig

3. XMLでプロファイルを宣言する

プロファイルはXMLで構成することもできます。 The タグにはプロフィール属性。該当するプロファイルのコンマ区切り値を取ります。

<beans profile="dev">
    <bean id="devDatasourceConfig" 
      class="org.baeldung.profiles.DevDatasourceConfig" />
</beans>

4. プロファイルを設定する

次のステップは、プロファイルをアクティブ化して設定し、それぞれのBeanがコンテナーに登録されるようにすることです。

これはさまざまな方法で実行できます。これについては、次のセクションで説明します。

4.1. WebApplicationInitializerインターフェイスを介してプログラムで

Webアプリケーションでは、 WebApplicationInitializer を使用して、ServletContextをプログラムで構成できます。

また、アクティブなプロファイルをプログラムで設定するのに非常に便利な場所です。

@Configuration
public class MyWebApplicationInitializer 
  implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
 
        servletContext.setInitParameter(
          "spring.profiles.active", "dev");
    }
}

4.2. ConfigurableEnvironmentを介してプログラムで

環境に直接プロファイルを設定することもできます。

@Autowired
private ConfigurableEnvironment env;
...
env.setActiveProfiles("someProfile");

4.3. web.xmlのコンテキストパラメータ

同様に、コンテキストパラメータを使用して、Webアプリケーションのweb.xmlファイルでアクティブなプロファイルを定義できます。

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/app-config.xml</param-value>
</context-param>
<context-param>
    <param-name>spring.profiles.active</param-name>
    <param-value>dev</param-value>
</context-param>

4.4. JVMシステムパラメータ

プロファイル名は、JVMシステムパラメータを介して渡すこともできます。 これらのプロファイルは、アプリケーションの起動時にアクティブになります。

-Dspring.profiles.active=dev

4.5. 環境変数

Unix環境では、プロファイルは環境変数を介してアクティブ化することもできます。

export spring_profiles_active=dev

4.6. Mavenプロファイル

Springプロファイルは、がspring.profiles.active構成プロパティを指定することにより、Mavenプロファイルを介してアクティブ化することもできます。

すべてのMavenプロファイルで、spring.profiles.activeプロパティを設定できます。

<profiles>
    <profile>
        <id>dev</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <spring.profiles.active>dev</spring.profiles.active>
        </properties>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <spring.profiles.active>prod</spring.profiles.active>
        </properties>
    </profile>
</profiles>

その値は、application.properties@spring.profiles.active@プレースホルダーを置き換えるために使用されます。

spring.profiles.active=@spring.profiles.active@

次に、pom.xmlでリソースフィルタリングを有効にする必要があります。

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
    ...
</build>

-P パラメーターを追加して、適用するMavenプロファイルを切り替えます。

mvn clean package -Pprod

このコマンドは、prodプロファイルのアプリケーションをパッケージ化します。 また、実行中にこのアプリケーションに spring.profiles.active value prodを適用します。

4.7. テストの@ActiveProfile

テストでは、 @ActiveProfile アノテーションを使用してアクティブなプロファイルを非常に簡単に指定し、特定のプロファイルを有効にします。

@ActiveProfiles("dev")

これまで、プロファイルをアクティブ化する複数の方法を見てきました。 次に、どちらが他方よりも優先され、複数を使用すると、優先度の高いものから低いものへと何が起こるかを見てみましょう。

  1. web.xmlのコンテキストパラメーター
  2. WebApplicationInitializer
  3. JVMシステムパラメータ
  4. 環境変数
  5. Mavenプロファイル

5. デフォルトのプロファイル

プロファイルを指定しないBeanは、defaultプロファイルに属します。

Springは、 spring.profiles.default プロパティを使用して、他のプロファイルがアクティブになっていないときにデフォルトのプロファイルを設定する方法も提供します。

6. アクティブなプロファイルを取得する

Springのアクティブなプロファイルは、Beanを有効/無効にするための@Profileアノテーションの動作を駆動します。 ただし、プログラムでアクティブなプロファイルのリストにアクセスすることもできます。

We have two ways to do it, using Environment or spring.profiles.active.

6.1. 環境を使用する

Environment オブジェクトを挿入することにより、アクティブなプロファイルにアクセスできます。

public class ProfileManager {
    @Autowired
    private Environment environment;

    public void getActiveProfiles() {
        for (String profileName : environment.getActiveProfiles()) {
            System.out.println("Currently active profile - " + profileName);
        }  
    }
}

6.2. Using spring.profiles.active

または、プロパティ spring.profiles.active を挿入して、プロファイルにアクセスすることもできます。

@Value("${spring.profiles.active}")
private String activeProfile;

ここで、 activeProfile 変数には、現在アクティブなプロファイルの名前が含まれ、複数ある場合は、コンマで区切られた名前が含まれます。

ただし、アクティブなプロファイルがまったくない場合にどうなるかを検討する必要があります。上記のコードでは、アクティブなプロファイルがないと、アプリケーションコンテキストを作成できません。 これにより、変数に挿入するためのプレースホルダーが欠落しているため、IllegalArgumentExceptionが発生します。

これを回避するために、デフォルト値を定義できます。

@Value("${spring.profiles.active:}")
private String activeProfile;

これで、アクティブなプロファイルがない場合、activeProfileには空の文字列が含まれます。

前の例のようにそれらのリストにアクセスしたい場合は、 splitting activeProfile変数でアクセスできます。

public class ProfileManager {
    @Value("${spring.profiles.active:}")
    private String activeProfiles;

    public String getActiveProfiles() {
        for (String profileName : activeProfiles.split(",")) {
            System.out.println("Currently active profile - " + profileName);
        }
    }
}

7. 例:プロファイルを使用した個別のデータソース構成

基本がわからなくなったので、実際の例を見てみましょう。

開発環境と本番環境の両方のデータソース構成を維持する必要があるシナリオを考えてみます。

両方のデータソース実装で実装する必要がある共通のインターフェイスDatasourceConfigを作成しましょう。

public interface DatasourceConfig {
    public void setup();
}

開発環境の構成は次のとおりです。

@Component
@Profile("dev")
public class DevDatasourceConfig implements DatasourceConfig {
    @Override
    public void setup() {
        System.out.println("Setting up datasource for DEV environment. ");
    }
}

そして、実稼働環境の構成:

@Component
@Profile("production")
public class ProductionDatasourceConfig implements DatasourceConfig {
    @Override
    public void setup() {
       System.out.println("Setting up datasource for PRODUCTION environment. ");
    }
}

次に、テストを作成して、DatasourceConfigインターフェイスを挿入しましょう。 アクティブなプロファイルに応じて、SpringはDevDatasourceConfigまたはProductionDatasourceConfigbeanを注入します。

public class SpringProfilesWithMavenPropertiesIntegrationTest {
    @Autowired
    DatasourceConfig datasourceConfig;

    public void setupDatasource() {
        datasourceConfig.setup();
    }
}

dev プロファイルがアクティブな場合、Springは DevDatasourceConfig オブジェクトを挿入し、 setup()メソッドを呼び出すと、次のように出力されます。

Setting up datasource for DEV environment.

8. SpringBootのプロファイル

Spring Bootは、これまでに概説したすべてのプロファイル構成をサポートしますが、いくつかの追加機能があります。

8.1. プロファイルのアクティブ化または設定

セクション4で紹介した初期化パラメータspring.profiles.activeは、現在アクティブなプロファイルを定義するためにSpringBootのプロパティとして設定することもできます。 これは、SpringBootが自動的に取得する標準のプロパティです。

spring.profiles.active=dev

ただし、Spring Boot 2.4以降では、このプロパティを spring.config.activate.on-profile と組み合わせて使用することはできません。これにより、 ConfigDataException ieが発生する可能性があります。 ] InvalidConfigDataPropertyExceptionまたはInactiveConfigDataAccessException)。

プログラムでプロファイルを設定するには、SpringApplicationクラスを使用することもできます。

SpringApplication.setAdditionalProfiles("dev");

Spring BootでMavenを使用してプロファイルを設定するには、 pom.xm lspring-boot-maven-pluginでプロファイル名を指定できます。

<plugins>
    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
            <profiles>
                <profile>dev</profile>
            </profiles>
        </configuration>
    </plugin>
    ...
</plugins>

SpringBoot固有のMavenゴールを実行します。

mvn spring-boot:run

8.2. プロファイル固有のプロパティファイル

ただし、Spring Bootがもたらす最も重要なプロファイル関連の機能は、プロファイル固有のプロパティファイルです。これらは、 application- {profile}.propertiesの形式で名前を付ける必要があります。

Spring Bootは、すべてのプロファイルの application.properties ファイルのプロパティと、指定されたプロファイルのプロファイル固有の.propertiesファイルのプロパティを自動的にロードします。

たとえば、 application-dev.propertiesおよびapplication-productionという名前の2つのファイルを使用して、devおよびproductionプロファイルに異なるデータソースを構成できます。プロパティ

application-production.properties ファイルで、MySqlデータソースを設定できます。

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db
spring.datasource.username=root
spring.datasource.password=root

次に、application-dev.propertiesファイルのdevプロファイルに同じプロパティを構成して、メモリ内のH2データベースを使用できます。

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa

このようにして、さまざまな環境にさまざまな構成を簡単に提供できます。

Spring Boot 2.4より前は、プロファイル固有のドキュメントからプロファイルをアクティブ化することが可能でした。 しかし、それはもはや事実ではありません。 それ以降のバージョンでは、フレームワークは、これらの状況でInvalidConfigDataPropertyExceptionまたはInactiveConfigDataAccessExceptionをスローします。

8.3. マルチドキュメントファイル

個別の環境のプロパティの定義をさらに簡素化するために、同じファイル内のすべてのプロパティをクラブ化し、セパレーターを使用してプロファイルを示すこともできます。

バージョン2.4以降、Spring Bootは、以前にサポートされていた YAML に加えて、プロパティファイルのマルチドキュメントファイルのサポートを拡張しました。 これで、同じapplication.propertiesで開発プロパティと本番プロパティを指定できます。

my.prop=used-always-in-all-profiles
#---
spring.config.activate.on-profile=dev
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db
spring.datasource.username=root
spring.datasource.password=root
#---
spring.config.activate.on-profile=production
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa

このファイルは、SpringBootによって上から下の順序で読み取られます。 つまり、上記の例の最後に my.prop などのプロパティがもう一度発生した場合、最後の値が考慮されます。

8.4. プロファイルグループ

Boot 2.4で追加されたもう1つの機能は、プロファイルグループです。 名前が示すように、類似したプロファイルをグループ化することができます

本番環境に複数の構成プロファイルがあるユースケースを考えてみましょう。 たとえば、本番環境環境では、データベースの場合は proddb 、スケジューラーの場合はprodquartzです。

application.properties ファイルを介してこれらのプロファイルを一度に有効にするには、次のように指定できます。

spring.profiles.group.production=proddb,prodquartz

したがって、 product プロファイルをアクティブにすると、proddbprodquartzもアクティブになります。

9. 結論

この記事では、Beanでプロファイルを定義する方法と、アプリケーションで適切なプロファイルを有効にする方法について説明しました。

最後に、単純ですが実際の例を使用して、プロファイルの理解を検証しました。

このチュートリアルの実装は、GitHubプロジェクトにあります。