1

Spring 4 には、ジェネリック型解決の主要な拡張機能が含まれていましたが、型引数が含まれている Bean クラスでパラメーター化されている場合、ジェネリック型の自動配線に問題があります。

外部サービスに送信されたジョブのステータスを追跡する必要があり、開始時に各ジョブのエントリを作成し、ポストバックを受信したときにそれをクリアまたは更新したいと考えています。私は通常、永続化戦略をサービス インターフェイスから分離するように努めているため、インターフェイスJobStatusと Spring Data Mongo クラスを用意していますMongoJobStatus implements JobStatus。外部サービスが ID (HTTP 502 など) を割り当てる機会を得る前にジョブが失敗する可能性があるJobStatusため、更新を識別するためにサービスに戻す必要があります。

interface JobStatusService<S extends JobStatus> {
    S beginJob(...);
    S updateJobStatus(S targetJob, Status newStatus);
    void finishJob(S targetJob);
}

したがって、ジョブの起動とポストバックの記録を処理する Spring コントローラーは次のようになります。コントローラー クラスは型パラメーターを持っているため、新しいステータス オブジェクトを格納してサービスに戻すことができます。

@Controller
public class JobController<JS extends JobStatus> {
    @Autowired JobStatusService<JS> jobService;

    ... handler method ...
    JS status = jobService.createJob(info, goes, here);
    // submit job via HTTP
    jobService.updateJobStatus(status, Status.PROCESSING);
    ...
}

私の MongoDB を利用した実装は次のようになります。

public class MongoJobStatusService implements JobStatusService<MongoJobStatus> {
    MongoJobStatus beginJob(...) {...}
    MongoJobStatus updateJobStatus(MongoJobStatus job, Status newStatus) {...}
}

起動しようとすると、Spring コンテキストがNoSuchBeanDefinitionExceptionforで失敗しJobStatusServiceます。を設定required=falseすると、MongoJobStatusServiceBean が適切にコンポーネント スキャンされ、コンテキストにインストールされることを確認しましたが、Spring は、そのクラスがそのパラメータ化されたジェネリック インターフェイスを実装していることを理解できないようです。

フィールドレベルでリテラル型引数として埋め込まれているのではなく、含まれている Bean レベルでパラメーター化された型引数を持つジェネリックインターフェイスを実装する Bean が必要であることを Spring に指定する方法はありますか?

4

3 に答える 3

2

追加してみてください:

 @Autowired 
 @Qualifier("mongoJobStatusService")
 JobStatusService<JS> jobService;

MongoJobStatusServiceBeanの名前を指定します。

于 2014-04-04T08:12:42.137 に答える
1

Spring コンテナーは、コントローラー クラスで受け入れ可能な型パラメーターを解決できないようですが、それらの型パラメーターが明示的に指定されている場合は、注入されたフィールドを解決できます。コントローラー クラスをリテラル型でサブクラス化することで、問題を回避することができました。

@Controller
public class MongoJobController<MongoJobStatus> {}

私はこれについてJIRA の問題を開いており、GitHub に最小限の例があります

于 2014-04-04T16:38:14.707 に答える