web-dev-qa-db-ja.com

Spring @Configurationクラスについて

Spring @Autowiredの使用法を理解する スプリング配線の他のオプションである@Configurationクラスの完全な知識ベースを作成したかったのです。

次のようなSpring XMLファイルがあるとします。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  <import resource="another-application-context.xml"/>

  <bean id="someBean" class="stack.overflow.spring.configuration.SomeClassImpl">
    <constructor-arg value="${some.interesting.property}" />
  </bean>

  <bean id="anotherBean" class="stack.overflow.spring.configuration.AnotherClassImpl">
    <constructor-arg ref="someBean"/>
    <constructor-arg ref="beanFromSomewhereElse"/>
  </bean>
</beans>

代わりに@Configurationを使用するにはどうすればよいですか?コード自体に影響はありますか?

103
Avi

XMLを@Configurationに移行しています

いくつかの手順でxmlを@Configurationに移行することができます。

  1. @Configuration注釈付きクラスを作成します。

    @Configuration
    public class MyApplicationContext {
    
    }
    
  2. <bean>タグごとに、@Beanアノテーションが付けられたメソッドを作成します。

    @Configuration
    public class MyApplicationContext {
    
      @Bean(name = "someBean")
      public SomeClass getSomeClass() {
        return new SomeClassImpl(someInterestingProperty); // We still need to inject someInterestingProperty
      }
    
      @Bean(name = "anotherBean")
      public AnotherClass getAnotherClass() {
        return new AnotherClassImpl(getSomeClass(), beanFromSomewhereElse); // We still need to inject beanFromSomewhereElse
      }
    }
    
  3. beanFromSomewhereElseをインポートするには、その定義をインポートする必要があります。 XMLで定義でき、@ImportResourceを使用します。

    @ImportResource("another-application-context.xml")
    @Configuration
    public class MyApplicationContext {
      ...  
    }
    

    Beanが別の@Configurationクラスで定義されている場合、@Importアノテーションを使用できます。

    @Import(OtherConfiguration.class)
    @Configuration
    public class MyApplicationContext {
      ...
    }
    
  4. 他のXMLまたは@Configurationクラスをインポートした後、次のように@Configurationクラスのプライベートメンバーを宣言することで、コンテキストで宣言するBeanを使用できます。

    @Autowired
    @Qualifier(value = "beanFromSomewhereElse")
    private final StrangeBean beanFromSomewhereElse;
    

    または、次のように@Qualifierを使用して、このbeanFromSomewhereElseに依存するBeanを定義するメソッドのパラメーターとして直接使用します。

    @Bean(name = "anotherBean")
    public AnotherClass getAnotherClass(@Qualifier (value = "beanFromSomewhereElse") final StrangeBean beanFromSomewhereElse) {
      return new AnotherClassImpl(getSomeClass(), beanFromSomewhereElse);
    }
    
  5. プロパティのインポートは、別のxmlまたは@ConfigurationクラスからBeanをインポートすることに非常に似ています。 @Qualifierを使用する代わりに、次のようなプロパティで@Valueを使用します。

    @Autowired
    @Value("${some.interesting.property}")
    private final String someInterestingProperty;
    

    これはSpEL式でも使用できます。

  6. SpringがそのようなクラスをBeanコンテナとして処理できるようにするには、このタグをコンテキストに追加して、メインxmlでこれをマークする必要があります。

    <context:annotation-config/>
    

    単純なBeanを作成する場合とまったく同じ@Configurationクラスをインポートできるようになりました。

    <bean class="some.package.MyApplicationContext"/>
    

    Spring XMLを完全に回避する方法はありますが、この答えの範囲には含まれていません。これらのオプションの1つは、私の答えをベースにしている ブログ投稿 で見つけることができます。


この方法を使用する利点と欠点

基本的に、いくつかの利点があるため、XMLを使用するよりもBeanを宣言するこの方法の方がはるかに快適です。

  1. Typos-@Configurationクラスはコンパイルされ、タイプミスはコンパイルを許可しません
  2. Fail fast(compile time)-Beanの注入を忘れると、XMLのように実行時ではなくコンパイル時に失敗します
  3. IDEでのナビゲートが簡単-依存関係ツリーを理解するためのBeanのコンストラクター間。
  4. 構成の起動を簡単にデバッグできます

欠点は、私が見ているように多くはありませんが、私が考えることができるいくつかがあります:

  1. Abuse-コードはXMLよりも悪用されやすい
  2. XMLを使用すると、コンパイル時には使用できないが、実行時には提供されるクラスに基づいて依存関係を定義できます。 @Configurationクラスを使用する場合、コンパイル時にクラスを使用可能にする必要があります。通常、それは問題ではありませんが、場合によっては問題になる可能性があります。

結論:XML、@Configuration、および annotations をアプリケーションコンテキストで組み合わせるのはまったく問題ありません。 Springは、Beanが宣言されたメソッドを気にしません。

143
Avi