3

春のデータの素晴らしさに触発されて、多くのコントローラーに拡張できる抽象的なRESTControllerを作成したいと思いました。次のクラスを作成しました。

@Controller
public abstract class RESTController<E, PK extends Serializable, R extends PagingAndSortingRepository<E, PK>>
{
    @Autowired
    private R repository;

    @RequestMapping(method=RequestMethod.GET, params={"id"})
    @ResponseBody 
    public E getEntity(@RequestParam PK id)
    {
        return repository.findOne(id);
    }

    ...
}

ジェネリックがリポジトリで@Autowiredを許可することを期待していましたが、次のエラーが発生します。

SEVERE: Allocate exception for servlet appServlet
org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.springframework.data.repository.PagingAndSortingRepository] is defined: expected single matching bean but found 3: [groupRepository, externalCourseRepository, managedCourseRepository]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:800)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)

エラーが何を示しているかを理解しています。@Autowiredには複数の一致があります。次のコントローラーを作成することで機能すると思ったので、混乱しています。

@Controller
@RequestMapping(value="/managedCourse")
public class ManagedCourseController extends RESTController<ManagedCourse, Long, ManagedCourseRepository>
{
    ...
}

これは、RESTControllerで次のようなメソッドを使用することで回避するのに十分簡単です。

protected abstract R getRepository();

次に、実装クラスでこれを実行します。

@Autowired
private ManagedCourseRepository repository;

@Override
protected ManagedCourseRepository getRepository() 
{
    return repository;
}

どうすればこれを機能させることができるかについて誰かが考えているのではないかと思っていました。

また、私はこの興味深いアリクルを見つけました。

4

3 に答える 3

1

Springでこの作業を行う方法はないと思います。私は以前にSpringIocのソースコードを読んだことがありますが、クラスレベルでの汎用宣言ではなく、フィールドまたはメソッドパラメータのみを考慮していることがわかりました。興味があれば、クラスorg.springframework.beans.factory.config.DependencyDescriptorを調べてください。そうすれば、私が言ったことを見つけることができます。

于 2012-06-01T05:21:52.310 に答える
1

この場合、実際にはアノテーションよりもXMLベースの配線をお勧めします。コントローラインスタンスでの不必要な重複を避けようとしているようです。単一のRESTコントローラークラスがある場合、コンテナーは必要な数のインスタンスをインスタンス化して、それぞれを異なるURIにマッピングできます。

アノテーションは、単一のインスタンスを作成することを計画している場合の省略形です。これはたまたまフォームベースのJ2EEセッションBeanの約90%をカバーしていますが、万能薬ではありません。

于 2012-06-01T14:06:17.770 に答える
0

Springはメンバーのタイプを使用してメンバーを「自動配線」するため、ジェネリックを使用すると、Springに注入する特定のタイプではなく、ジェネリックタイプ情報のみを提供します。

于 2012-06-01T04:59:30.087 に答える