2012-06-01 7 views
3

봄 데이터 awedomeness에서 영감을 얻었습니다. 많은 컨트롤러에서 확장 할 수있는 추상 RESTController를 만들고 싶었습니다. 내가 제네릭이 저장소에 @Autowired 날을 허용 것이라고 기대했다 그러나 나는 다음과 같은 오류 얻을spring @Autowired가 java generics와 함께 작동하지 않는 이유는 무엇입니까?

@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); 
    } 

    ... 
} 

:

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; 
} 

나는이 작업을 수행 할 수있는 방법에 대한 생각이 있는지 궁금합니다.

또한 this 흥미로운 aritcle을 발견했습니다.

+0

작동하는지 모르겠지만 'Autowired'외에 '한정자'주석을 사용해보십시오. – Dani

+0

무언가를 놓친다면 용서해주세요.하지만 구현 클래스를 모르는 경우 추상 클래스 도움말에 한정자를 추가하면 어떻게됩니까? 당신의 응답에 감사드립니다. 설명 해주십시오. – testing123

답변

1

사실이 경우 주석을 통해 XML 기반 배선을 권장합니다. 그것은 당신이 컨트롤러 인스턴스에서 많은 불필요한 중복을 피하려고하는 것 같습니다. 단일 REST 컨트롤러 클래스가있는 경우 컨테이너는 필요한만큼 인스턴스를 인스턴스화하여 각 인스턴스를 다른 URI에 매핑 할 수 있습니다.

어노테이션은 단일 인스턴스를 작성할 계획 인 경우 더 간단합니다. 이는 폼 기반 J2EE 세션 빈의 약 90 %를 차지하지만, 만병 통치약이 아닙니다.

0

스프링은 멤버의 유형을 사용하여 자동 와이어 링합니다. 따라서 제네릭을 사용하면 스프링이 사용자에게 주입하기를 원하는 특정 유형이 아닌 일반 유형 정보 만 제공합니다.

1

스프링으로이 작업을 수행 할 방법이 없다고 생각합니다. 이전에 Spring Ioc의 소스 코드를 읽었으며 Class Level의 Generic Declaration은 신경 쓰지 않고 Field 또는 Method Parameter 만 신경 써야한다. 관심이 있다면 org.springframework.beans.factory.config.DependencyDescriptor 클래스를 살펴보고 내가 말한 것을 찾을 것이다.

관련 문제