web-dev-qa-db-ja.com

spring @Autowireプロパティとセッター

プロパティへの@Autowiredの注釈付けとセッターでの注釈付けの違いは何ですか?

私の知る限り、両方とも同じ結果になりますが、どちらか一方を使用する理由はありますか?

更新(より簡潔にするため)

これに違いはありますか

package com.tutorialspoint;

import org.springframework.beans.factory.annotation.Autowired;

public class TextEditor {
   private SpellChecker spellChecker;

   @Autowired
   public void setSpellChecker( SpellChecker spellChecker ){
      this.spellChecker = spellChecker;
   }

   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}

この

package com.tutorialspoint;

import org.springframework.beans.factory.annotation.Autowired;

public class TextEditor {
   @Autowired
   private SpellChecker spellChecker;

   public TextEditor() {
      System.out.println("Inside TextEditor constructor." );
   }

   public void spellCheck(){
      spellChecker.checkSpelling();
   }
}
29
luso

@Autowired注釈、セッターメソッドは必要ありません。 Beanのコンストラクターでオブジェクトの割り当て/作成が完了すると、Springはこの注釈をスキャンし、注釈を付けたオブジェクトインスタンスを注入します。

セッターがあり、xml configをまだ使用している場合は、明示的にプロパティを設定します。

そうは言っても、コンストラクターとセッターメソッドに自動配線アノテーションを付けることができます。これにより、後でSpringから柔軟に移動できるようになります(そうはしませんが)。

19
SMA

クラスAのインスタンスが必要な場合もありますが、クラスのフィールドにAを格納しません。ワンショット操作を実行するには、Aが必要です。または、Aを使用してBのインスタンスを取得し、フィールドにBを格納しています。

これらの場合、セッター(またはコンストラクター)自動配線がより適しています。未使用のクラスレベルのフィールドはありません。

具体例:RabbitTemplate(RabbitMQにメッセージを送信するオブジェクト)を構築する必要があります。構築するには、 ConnectionFactoryhttp://docs.spring.io/spring-amqp/docs/latest_ga/api/org/springframework/amqp/rabbit/core/RabbitTemplate.html#RabbitTemplate- org.springframework.amqp.rabbit.connection.ConnectionFactory-

そのConnectionFactoryを保存する必要はありません。その場合、次のようなコード:

Class MyClass {
private RabbitTemplate template;

@Autowired 
void setConnectionFactory(ConnectionFactory c) {
    template=new RabbitTemplate(c);
}
}

...ConnectionFactoryフィールドを直接自動配線するよりも役立ちます。

この例では、オブジェクトは常に完全に構​​築されるため、コンストラクターレベルでの自動配線はさらに改善されます。 ConnectionFactoryは必須の依存関係であり、オプションの依存関係ではないことは明らかです。

17
Bartosz Bilicki

可能であれば、セッターを避ける必要があります。必要ない場合は、存在しないほうがいいでしょう?

個人的には、Guiceが私に書き込みを許可することを好みます

public class TextEditor {
   private final SpellChecker spellChecker;

   @Inject public TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void spellCheck(){
      spellChecker.checkSpelling();
   }
}

これはさらに一歩進んでいます。finalフィールドを使用すると、変更されないことがわかり、 マルチスレッドの可視性保証 が得られます。

1
maaartinus

自動配線は、プロジェクト全体で一貫して使用される場合に最適に機能します。自動配線が一般的に使用されない場合、開発者が1つまたは2つのBean定義のみを配線するためにそれを使用することは混乱を招く可能性があります。フィールドで@Autowiredを使用すると、セッターメソッドは必要ありません。セッターメソッドを使用すると、クラスが小さくなり読みやすくなりますが、一方でクラスのモックが少し見苦しくなります。

プロパティとconstructor-arg設定の明示的な依存関係は、常に自動配線をオーバーライドします。プリミティブ、文字列、クラス(およびそのような単純なプロパティの配列)などのいわゆる単純なプロパティを自動配線することはできません。この制限は仕様によるものです。

自動配線は、明示的な配線ほど正確ではありません。 Springでは、予期しない結果が生じる可能性がある曖昧さの場合に推測を避けるように注意しており、Spring管理オブジェクト間の関係は明示的に文書化されなくなりました。

配線情報は、Springコンテナからドキュメントを生成する可能性のあるツールでは利用できない場合があります。

コンテナ内の複数のBean定義は、自動配線されるセッターメソッドまたはコンストラクター引数で指定されたタイプと一致する場合があります。配列、コレクション、またはマップの場合、これは必ずしも問題ではありません。ただし、単一の値を期待する依存関係の場合、このあいまいさはarbitrarily意的に解決されません。一意のBean定義が利用できない場合、例外がスローされます。

1

@Autowired注釈propertyを使用すると、springはspring.xmlを使用してプロパティを開始します。この場合、セッターは必要ありません。

@Autowired注釈[setterを使用する場合、カスタムコードを追加できるこのセッターメソッドを使用してこのプロパティを開始することを指定します。 このプロパティで他のプロパティを初期化するのように。

使用例: JdbcTemplateを使用してDAO操作を使用する場合、JdbcTemplateへの入力としてDataSourceが必要ですが、DataSourceはそれ自体のプロパティとしては必要ありません。したがって、DataSource Setterを自動配線することにより、DataSource Setterを使用してJdbcTempateを初期化できます。以下のコードをご覧ください:

class DaoDemo{
   //@Autowired
   //private DataSource dataSource;
   private JdbcTemplate jdbcTemplate;

   @Autowired
   public void setDataSource(DataSource dataSource){
     //this.dataSource = dataSource;  
     this.jdbcTemplate = new JdbcTemplate(dataSource);
   }

   public int getTableRowCount(){
      String sql = "SELECT COUNT(*) FROM DEMOTABLE";
      //jdbcTemplate.setDataSource(dataSource);    //No need to do this as its done in DataSource Setter now.
      return jdbcTemplate.queryForObject(sql,Integer.class);

}

上記のコードでは、dataSourceの唯一の使用は、JdbcTemplateに渡されることでした。したがって、ここではdataSourceのプロパティを作成しても意味がありません。そのため、DataSource Beanのセッターメソッドの@Autowiredを使用して、spring.xmlからエントリを取得し、その特定の時間にそれを使用します。

1
Sahil Chhabra

OPTIONALプロパティで@Autowiredを使用しても機能しない場合が1つあります。

そのプロパティを使用して何らかの初期化を行いたい場合、コンストラクターが呼び出される前に設定されない場合があり、オプションであるため、コンストラクターの引数として設定することはできません。

その場合は、@ Autowiredセッターメソッドを使用することをお勧めします。プロパティが自動配線されたら、初期化を実行できます。

0
AdamSkwersky