アノテーションインターフェース Configuration


クラスが 1 つ以上の @Bean メソッドを宣言し、Spring コンテナーによって処理されて、実行時にこれらの Bean の Bean 定義とサービスリクエストを生成できることを示します。
 @Configuration
 public class AppConfig {

     @Bean
     public MyBean myBean() {
         // instantiate, configure and return bean ...
     }
 }

@Configuration クラスのブートストラップ

AnnotationConfigApplicationContext 経由

@Configuration クラスは通常、AnnotationConfigApplicationContext またはその Web 対応バリアント AnnotationConfigWebApplicationContext を使用してブートストラップされます。前者の簡単な例を次に示します。

 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
 ctx.register(AppConfig.class);
 ctx.refresh();
 MyBean myBean = ctx.getBean(MyBean.class);
 // use myBean ...
 

詳細については、AnnotationConfigApplicationContext javadoc を参照してください。Servlet コンテナーでの Web 構成手順については、AnnotationConfigWebApplicationContext を参照してください。

Spring <beans> XML 経由

AnnotationConfigApplicationContext に対して @Configuration クラスを直接登録する代わりに、@Configuration クラスを Spring XML ファイル内の通常の <bean> 定義として宣言できます。

 <beans>
    <context:annotation-config/>
    <bean class="com.acme.AppConfig"/>
 </beans>
 

上記の例では、@Configuration クラスの処理を容易にする ConfigurationClassPostProcessor およびその他のアノテーション関連のポストプロセッサーを有効にするために、<context:annotation-config/> が必要です。

コンポーネントスキャン経由

@Configuration には @Component のメタアノテーションが付けられているため、@Configuration クラスがコンポーネントスキャンの候補になります。たとえば、@ComponentScan または Spring XML の <context:component-scan/> 要素を使用します。通常の @Component と同様に @Autowired/@InjectEE を利用することもできます。特に、単一のコンストラクターが存在する場合、オートワイヤーセマンティクスはそのコンストラクターに対して透過的に適用されます。

 @Configuration
 public class AppConfig {

     private final SomeBean someBean;

     public AppConfig(SomeBean someBean) {
         this.someBean = someBean;
     }

     // @Bean definition using "SomeBean"

 }

@Configuration クラスは、コンポーネントスキャンを使用してブートストラップされるだけでなく、@ComponentScan アノテーションを使用してコンポーネントスキャンを構成することもできます。

 @Configuration
 @ComponentScan("com.acme.app.services")
 public class AppConfig {
     // various @Bean definitions ...
 }

詳細については、@ComponentScan javadoc を参照してください。

外部化された値の操作

Environment API の使用

Spring Environment を @Configuration クラスに挿入することにより、外部化された値を検索できます。たとえば、@Autowired アノテーションを使用します。

 @Configuration
 public class AppConfig {

     @Autowired Environment env;

     @Bean
     public MyBean myBean() {
         MyBean myBean = new MyBean();
         myBean.setName(env.getProperty("bean.name"));
         return myBean;
     }
 }

Environment を介して解決されるプロパティは、1 つ以上の「プロパティソース」オブジェクトに存在し、@Configuration クラスは、@PropertySource アノテーションを使用して Environment オブジェクトにプロパティソースを提供できます。

 @Configuration
 @PropertySource("classpath:/com/acme/app.properties")
 public class AppConfig {

     @Inject Environment env;

     @Bean
     public MyBean myBean() {
         return new MyBean(env.getProperty("bean.name"));
     }
 }

詳細については、Environment および @PropertySource javadoc を参照してください。

@Value アノテーションを使用する

@Value アノテーションを使用して、外部化された値を @Configuration クラスに注入できます。

 @Configuration
 @PropertySource("classpath:/com/acme/app.properties")
 public class AppConfig {

     @Value("${bean.name}") String beanName;

     @Bean
     public MyBean myBean() {
         return new MyBean(beanName);
     }
 }

このアプローチは、<context:property-placeholder/> を介して XML 構成で自動的に有効するか、専用の static @Bean メソッドを介して @Configuration クラスで明示的に有効にできる Spring の PropertySourcesPlaceholderConfigurer と組み合わせて使用されることがよくあります(@Bean の javadoc の「BeanFactoryPostProcessor- @Bean メソッドを返すことに関する注記」を参照)詳細)。ただし、static @Bean メソッドを介した PropertySourcesPlaceholderConfigurer の明示的な登録は、通常、プレースホルダー構文などの構成をカスタマイズする必要がある場合にのみ必要です。具体的には、Bean ポストプロセッサー(PropertySourcesPlaceholderConfigurer など)が登録されていない場合 ApplicationContextエンベディッドバリューリゾルバーである Spring は、Environment に登録されているプロパティソースに対してプレースホルダーを解決するデフォルトのエンベディッドバリューリゾルバーを登録します。@ImportResource を使用して Spring XML で @Configuration クラスを作成する方法については、以下のセクションを参照してください。@Value javadoc を参照してください。PropertySourcesPlaceholderConfigurer などの BeanFactoryPostProcessor 型の操作の詳細については、@Bean javadoc を参照してください。

@Configuration クラスの作成

@Import アノテーションを使用する場合

@Configuration クラスは、@Import アノテーションを使用して構成できます。これは、Spring XML で <import> が機能する方法と同様です。@Configuration オブジェクトはコンテナー内で Spring Bean として管理されるため、インポートされた構成が挿入される場合があります。— たとえば、コンストラクターインジェクション経由:

 @Configuration
 public class DatabaseConfig {

     @Bean
     public DataSource dataSource() {
         // instantiate, configure and return DataSource
     }
 }

 @Configuration
 @Import(DatabaseConfig.class)
 public class AppConfig {

     private final DatabaseConfig dataConfig;

     public AppConfig(DatabaseConfig dataConfig) {
         this.dataConfig = dataConfig;
     }

     @Bean
     public MyBean myBean() {
         // reference the dataSource() bean method
         return new MyBean(dataConfig.dataSource());
     }
 }

これで、Spring コンテキストに対して AppConfig のみを登録することにより、AppConfig とインポートされた DatabaseConfig の両方をブートストラップできます。

 new AnnotationConfigApplicationContext(AppConfig.class);

@Profile アノテーションを使用する場合

@Configuration クラスは @Profile アノテーションでマークされ、特定のプロファイルがアクティブな場合にのみ処理されることを示します。

 @Profile("development")
 @Configuration
 public class EmbeddedDatabaseConfig {

     @Bean
     public DataSource dataSource() {
         // instantiate, configure and return embedded DataSource
     }
 }

 @Profile("production")
 @Configuration
 public class ProductionDatabaseConfig {

     @Bean
     public DataSource dataSource() {
         // instantiate, configure and return production DataSource
     }
 }

または、@Bean メソッドレベルでプロファイル条件を宣言することもできます。たとえば、同じ構成クラス内の代替 Bean バリアントの場合:

 @Configuration
 public class ProfileDatabaseConfig {

     @Bean("dataSource")
     @Profile("development")
     public DataSource embeddedDatabase() { ... }

     @Bean("dataSource")
     @Profile("production")
     public DataSource productionDatabase() { ... }
 }

詳細については、@Profile および Environment javadoc を参照してください。

@ImportResource アノテーションを使用した Spring XML

上記のように、@Configuration クラスは、Spring XML ファイル内の通常の Spring <bean> 定義として宣言できます。@ImportResource アノテーションを使用して、Spring XML 構成ファイルを @Configuration クラスにインポートすることもできます。XML からインポートされた Bean 定義を挿入できます。— たとえば、@Inject アノテーションを使用します。

 @Configuration
 @ImportResource("classpath:/com/acme/database-config.xml")
 public class AppConfig {

     @Inject DataSource dataSource; // from XML

     @Bean
     public MyBean myBean() {
         // inject the XML-defined dataSource bean
         return new MyBean(this.dataSource);
     }
 }

ネストされた @Configuration クラスを使用

@Configuration クラスは、次のように相互にネストできます。

 @Configuration
 public class AppConfig {

     @Inject DataSource dataSource;

     @Bean
     public MyBean myBean() {
         return new MyBean(dataSource);
     }

     @Configuration
     static class DatabaseConfig {
         @Bean
         DataSource dataSource() {
             return new EmbeddedDatabaseBuilder().build();
         }
     }
 }

そのような配置をブートストラップするとき、AppConfig のみをアプリケーションコンテキストに対して登録する必要があります。ネストされた @Configuration クラスであるため、DatabaseConfig  は自動的に登録されます。これにより、AppConfig と DatabaseConfig の関連がすでに暗黙的に明確である場合に、@Import アノテーションを使用する必要がなくなります。

また、ネストされた @Configuration クラスを使用して、@Profile アノテーションを効果的に使用し、同じ Bean の 2 つのオプションを外側の @Configuration クラスに提供することもできます。

遅延初期化の構成

デフォルトでは、@Bean メソッドはコンテナーのブートストラップ時に積極的にインスタンス化さます。これを回避するには、@Configuration を @Lazy アノテーションと組み合わせて使用して、クラス内で宣言されたすべての @Bean メソッドがデフォルトで遅延初期化されることを示します。@Lazy は、個々の @Bean メソッドでも使用できることに注意してください。

@Configuration クラスのテストサポート

spring-test モジュールで使用可能な Spring TestContext フレームワークは、コンポーネントクラス参照の配列(通常は @Configuration または @Component クラス)を受け入れることができる @ContextConfiguration アノテーションを提供します。

 @ExtendWith(SpringExtension.class)
 @ContextConfiguration(classes = {AppConfig.class, DatabaseConfig.class})
 class MyTests {

     @Autowired MyBean myBean;

     @Autowired DataSource dataSource;

     @Test
     void test() {
         // assertions against myBean ...
     }
 }

詳細については、TestContext フレームワークリファレンスドキュメントを参照してください。

@Enable アノテーションを使用して組み込み Spring 機能を有効にする

非同期メソッド実行、スケジュールされたタスク実行、アノテーション駆動型トランザクション管理、さらには Spring MVC などの Spring 機能は、それぞれの "@Enable" アノテーションを使用して @Configuration クラスから有効化および構成できます。詳細は @EnableAsync@EnableScheduling@EnableTransactionManagement@EnableAspectJAutoProxy@EnableWebMvc を参照してください。

@Configuration クラスを作成する際の制約

  • 構成クラスはクラスとして(つまり、ファクトリメソッドから返されるインスタンスとしてではなく)提供する必要があります。これにより、生成されたサブクラスを介してランタイムを強化できます。
  • proxyBeanMethods フラグが false に設定されていない場合(実行時に生成されるサブクラスは不要)を除き、構成クラスは最終ではない(実行時にサブクラスを許可する)必要があります。
  • 構成クラスは非ローカルでなければなりません(つまり、メソッド内で宣言できません)。
  • ネストされた構成クラスはすべて static として宣言する必要があります。
  • @Bean メソッドは、さらに構成クラスを作成しない場合があります(そのようなインスタンスは、構成アノテーションが検出されないまま、通常の Bean として扱われます)。
導入:
3.0
作成者:
Rod Johnson, Chris Beams, Juergen Hoeller
関連事項:
  • オプション要素のサマリー

    オプション要素
    修飾子と型
    オプションの要素
    説明
    boolean
    @Bean メソッドに一意のメソッド名を付ける必要があるかどうかを指定します。そうでない場合は、偶発的なオーバーロードを防ぐために例外を発生させます。
    boolean
    Bean ライフサイクルの動作を実施するために、@Bean メソッドをプロキシするかどうかを指定します。
    @Configuration クラスに関連付けられている Spring Bean 定義の名前を明示的に指定します。
  • 要素の詳細

    • value

      @Configuration クラスに関連付けられている Spring Bean 定義の名前を明示的に指定します。指定しない場合(一般的なケース)、Bean 名が自動的に生成されます。

      カスタム名は、@Configuration クラスがコンポーネントスキャンによって取得されるか、AnnotationConfigApplicationContext に直接提供される場合にのみ適用されます。@Configuration クラスが従来の XML Bean 定義として登録されている場合、Bean 要素の名前 / ID が優先されます。

      Component.value() のエイリアス。

      戻り値:
      明示的なコンポーネント名(存在する場合) (それ以外の場合は空の文字列)
      関連事項:
      デフォルト:
      ""
    • proxyBeanMethods

      boolean proxyBeanMethods
      Bean ライフサイクルの動作を実施するために、@Bean メソッドをプロキシするかどうかを指定します。ユーザーコードで @Bean メソッドを直接呼び出した場合でも、共有シングルトン Bean インスタンスを返す。この機能には、ランタイム生成された CGLIB サブクラスを介して実装されるメソッドインターセプトが必要です。これには、構成クラスやそのメソッドが final の宣言を許可されていないなどの制限があります。

      デフォルトは true であり、構成クラス内の直接メソッド呼び出しを介した「Bean 間参照」、およびこの構成の @Bean メソッドへの外部呼び出しを許可します。別の構成クラスから。この特定の構成の各 @Bean メソッドは自己完結型であり、コンテナー使用のためのプレーンファクトリメソッドとして設計されているため、これが必要ない場合は、CGLIB サブクラス処理を回避するために、このフラグを false に切り替えます。

      Bean メソッドのインターセプトをオフにすると、@Configuration 以外のクラスで宣言された場合と同様に、@Bean メソッドが個別に効果的に処理されます(別名: 「@Bean Lite モード」(@Bean's javadoc を参照)。@Configuration ステレオタイプを削除するのと同じ動作になります。

      導入:
      5.2
      デフォルト:
      true
    • enforceUniqueMethods

      boolean enforceUniqueMethods
      @Bean メソッドに一意のメソッド名を付ける必要があるかどうかを指定します。そうでない場合は、偶発的なオーバーロードを防ぐために例外を発生させます。

      デフォルトは true であり、同じ Bean 定義のオーバーロードされたファクトリメソッドとして解釈される偶発的なメソッドのオーバーロードを防ぎます(個々の条件などで別々の Bean 定義とは対照的です)。これらのセマンティクスに従ってメソッドのオーバーロードを可能にし、偶発的なオーバーラップのリスクを受け入れるために、このフラグを false に切り替えます。

      導入:
      6.0
      デフォルト:
      true