web-dev-qa-db-ja.com

Springアノテーションの違い

質問:

1)@Component@Configurationの違いは?

どちらもXMLにコードを配置する必要性をなくしましたが、これらの間に違いはありませんでした。

2)@Autowired@Inject、および@Resourceの違いは何ですか?
-どの場合に使用しますか?
-それぞれの長所と短所は何ですか?

40
Anand

@Component@Configurationは、実際には非常に異なるタイプの注釈です。

@Componentおよび同様の注釈(@Service@Repositoryなど)およびその JSR-3 対応する@Namedを使用すると、<context:component-scan/>または@ComponentScanで自動スキャンすることでピックアップされるBeanを宣言して、そのため、指定されたBeanをXMLの<bean ... />タグで宣言することとほぼ同等です。このBeanタイプは、標準のプロキシ作成ポリシーに準拠します。

@Configuration注釈は、XML構成ファイルの置き換えとして設計されました。 @Configuration注釈付きBeanを作成するために、Springは常にCGLIBを使用して@Configuration注釈付きクラスをサブクラス化し、その@Bean注釈付きメソッドをオーバーライドしてBeanルックアップメソッドで置き換え、シングルトンBeanを1回だけ作成します。 (SpringはCGLIBを使用してインターセプトしませんinternalnormal Spring Beanのメソッド呼び出し、代わりにプロキシの別のインスタンスを作成します(JDKプロキシと同じ方法)これにより、プロキシを使用してカーディナリティの不一致を回避できます-たとえば、プロキシシングルトンは現在のセッションBeanを取得できますが、これはクラス継承のみでは不可能です。それにもかかわらず、@Configuration注釈付きクラスは、annotated(@Autowired@Injectなど)フィールドとプロパティを使用して、コンテナからBean(および他の@Configuration注釈付きBeanも)を要求できます。

documentation の4.12.5セクションから

@Configuration
public class AppConfig {

  @Bean
  public ClientService clientService1() {
    ClientServiceImpl clientService = new ClientServiceImpl();
    clientService.setClientDao(clientDao());
    return clientService;
  }
  @Bean
  public ClientService clientService2() {
    ClientServiceImpl clientService = new ClientServiceImpl();
    clientService.setClientDao(clientDao());
    return clientService;
  }

  @Bean
  public ClientDao clientDao() {
    return new ClientDaoImpl();
  }
}

上記の例では、1つのClientDaoインスタンスのみが作成されます。

@AutowiredはSpringアノテーションであり、@InjectはJSR-330アノテーションです。 @Inject@Autowiredまたは@Autowired(required=true)と同等ですが、JSR-330の@Injectannotationでは@Autowired(required=false)動作を取得できません。この注釈は、常にタイプごとの自動配線を使用します。

Springは JSR-25@Resourceアノテーションをかなり特別な方法で実装します。 @Resourceは元々Java EEでJNDIリソースを見つけるために設計されましたが、Springは適用範囲を広げてコンテナ内の任意のBeanにワイヤリングできるようにします(JNDIリソースは、 SimpleJndiBeanFactory )。対応するBeanの名前は、@Resourceアノテーションのname属性として指定でき、名前が指定されていない場合は、注釈付きフィールドまたはプロパティの名前が使用されます。プロパティ名のBeanが見つからなかった場合、スプリングはタイプ別の配線にフォールバックします。

AlphaClass Beanという名前のbeanAlphaBetaClass Bean beanBetaがあると想像してくださいコンテナ。

@Resource 
BetaClass something;  // Wires to beanBeta - by-type

@Resource 
BetaClass beanAlpha;  // Will throw exception, because "beanAlpha" is not BetaClass -> it's a bad idea to use @Resource as a replacement of @Autowired

@Resource 
Object beanAlpha;  //Wires to beanAlpha - by-name

したがって、@Resourceアノテーションを使用する場合は、常にリソース名を明示的に指定することをお勧めします。

ドキュメント

春の注釈

Bean標準アノテーション

updateshevchikが指摘したように、JSR参照を修正しました。 DI固有の注釈は、Google(Guice Framework)およびSpringSource(Spring Framework)エンジニアによって開発されたJSR-330によって提供されます。 @ResourceはJNDIベースであり、 JSR-25 によって提供されます。

54
Boris Treukhov

@Component<bean>と同等です。
@Configuration<beans>と同等です。

22
xyz

上記のほとんどの回答では、ユーザーは@Componentと@ Configurationの目的が異なると言うことをお勧めします。しかし、私はそれが実際に起こっているのを見ていません。

しかし、私は単純なSpring MVCアプリケーションを持っています。

@Configuration
    public class SpringConfiguration {

@Bean
public  InternalResourceViewResolver initViewResolver(){
    InternalResourceViewResolver x = new InternalResourceViewResolver();
    x.setPrefix("/WEB-INF/jsp/");
    x.setSuffix(".jsp");
    return x;
}

}

このメインクラスは、@ Configurationではなく@Componentとして注釈が付けられていても正常に機能します。

同様に、@ Beanアノテーションが付けられたメソッドがある場合、@ Componentアノテーションが付けられたクラス内では、コンテキストが解放されたときにそれらのBeanが作成されます。

だから、メインの構成クラスを@Configurationとしてマークし、他のクラスを@Componentとしてマークするのは、コードを読みやすくするためだけだと思います。実際の実行に関しては、違いはないようです。

5
Kaushik Lele

@Autowired@Inject、および@Resourceの違いについては、 here を参照してください。ここで、詳細な説明と比較を行うことができます。

最初の違いに関係するもの:@ConfigurationXMLベースの構成の代替として使用されます。クラスはJavaベースの構成に使用されるものとしてマークされます。 here を参照してください。次に、@Componentは、クラスをSpringによってインスタンス化されるものとしてマークするために実際に使用され、@Configuration@Component注釈によってメタ注釈が付けられます。

@Component@Configurationは異なる目的で使用されるため、それらを比較しても意味がありません。

1)XML構成が必要な場合は、@ Configurationを無視します。これはJavaベースの構成にのみ役立つためです。 XML構成は、使用可能なサンプルが他にもあるため、Springに不慣れな人にはおそらく最適です。

@Component注釈付きクラスは、コンポーネントのスキャン中に取得されます。それらを使用して、Spring Beanとして公開するクラスにラベルを付けます。繰り返しますが、XML構成ですべてのBeanを宣言し、@ Componentを完全に無視することができます。

2)アプリケーションをSpringに結び付けたい場合は、javaxに相当する@Injectではなく@Autowireを使用します。私は、Springへの依存を受け入れることが最良の開始方法であることを提案します。

2
Rich Cowin