3

私はJavaとSpringに不慣れで、C#と.NETの世界から来ているので、我慢してください-私がやろうとしていることは、的外れかもしれません...

XML構成ではなく、Java構成とアノテーションを使用してSpring DIを構成しようとしていますが、いくつかの問題があります。これはスタンドアロンアプリケーション用であり、Webアプリ用ではありません。私はspringsourceのドキュメントに目を通しましたが、私の非常に基本的な構成が正しいはずだと言える限り、そうではありません。以下のコードをご覧ください。

Java構成注釈付きクラス:

package birdalerter.common;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import birdalerter.process.ISightingsProcessor;
import birdalerter.process.SightingsProcessor;

@Configuration
@ComponentScan({"birdalerter.process", "birdalerter.common"})
public class AppConfig {
    @Bean
    @Scope("prototype")
    public ISightingsProcessor sightingsProcessor(){
        return new SightingsProcessor();
    }
}

ISightingsProcessorインターフェースを実装するコンポーネントを構成します。

package birdalerter.process;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;

import org.springframework.stereotype.Component;

import birdalerter.domainobjects.IBirdSighting;
@Component
public class SightingsProcessor implements ISightingsProcessor{

    private LinkedBlockingQueue<IBirdSighting> queue;
    private List<ISightingVisitor> sightingVisitors = new ArrayList<ISightingVisitor>();

    public SightingsProcessor(){
    }

    ...
}

ファクトリコンポーネントの構成:

package birdalerter.process;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
public class ProcessorFactory {
    private ISightingsProcessor sightingsProcessor;

    @Autowired
    @Required
    private void setSightingsProcessor(ISightingsProcessor sightingsProcessor){
        this.sightingsProcessor = sightingsProcessor;
    }

    public ISightingsProcessor getSightingsProcessor(){
        return this.sightingsProcessor;
    }
}

AnnotationConfigApplicationContextを接続し、テストします。

@Test
public void testProcessingDI(){
    @SuppressWarnings("resource")
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    context.register(AppConfig.class);
    context.refresh();


    ISightingsProcessor processor = new ProcessorFactory().getSightingsProcessor();
    System.out.println(processor);
    Assert.assertTrue(processor != null);
}

SightingsProcessorはセッター注入されておらず、返されたオブジェクトがnullであるため、アサートは失敗しています。うまくいけば、私は非常に明白な何かを逃しました。

前もって感謝します。

メリトンに応えて編集:

メリトンの答えをありがとう。

Springが新しく作成されたオブジェクトを知らないのはなぜですか?Springは、アプリケーションのライフサイクル全体を通じて依存関係を維持せず、Beanとして構成された新しいオブジェクトが作成されたときに適切に注入しませんか?

正直に言うと、直接使用したくありませんcontext.getBean(ISightingsProcessor.class)。手動で介入することなく、setterメソッドに依存性を注入したいと思います。

私はインターフェースが拡張するときにを使用しProcessorFactoryています-実装オブジェクトはスレッドとして開始されます。アプリケーションは、n *個のスレッドを持つように構成可能であり、各スレッドはループ反復内で開始されます。メソッド宣言内にアノテーションを含めることは不可能だと思います(間違っている可能性がありますので、教えてください) 。そのため、ファクトリを使用して、注入された具象クラスの新しいインスタンスを提供します。ISightingsProcessorRunnable@AutowiredISightingsProcessor

はい、@Scope注釈について調べたところです。その通りです。宣言に移動する必要がありますAppConfig @Bean(この編集で行いました)。ありがとうございます。

4

1 に答える 1

1
ISightingsProcessor processor = new ProcessorFactory().getSightingsProcessor();

これにより、ProcessorFactoryのコンストラクターが呼び出され、次にコンストラクターが作成したインスタンスのゲッターが呼び出されます。Springはその新しく作成されたオブジェクトを知ることができないため、その依存関係を注入しません。代わりに、SpringにProcessorFactoryを要求する必要があります。

ProcessorFactory pf = context.getBean(ProcessorFactory.class);
ISightingsProcessor processor = pf.getSightingsProcessor();

とはいえ、なぜクラスProcessorFactoryが必要なのかはわかりません。ISightingsProcessorを直接取得することもできます。

ISightingsProcessor processor = context.getBean(ISightingsProcessor.class);

さらに、「Javaベースの構成」とコンポーネントのスキャンは、Beanを宣言するための独立した方法です。したがって、現在、ISightingsProcessorを2回宣言しています。1回は@Beanアノテーションが付けられたファクトリメソッドを使用し、もう1回はクラスのコンポーネントスキャンと@Componentアノテーションを使用します。どちらかを実行すると実行されます。実際、両方を実行すると、一方のBean定義が他方をオーバーライドする可能性があります。

ああ、@ScopeアノテーションはBean定義(@Beanまたはでアノテーションを付けるもの@Component)用です。注入ポイント()では無視される可能性があります@Autowired

于 2013-01-20T13:47:36.210 に答える