복붙노트

[SPRING] Spring에서 Generic type <T>의 Bean을 Autowire하는 법?

SPRING

Spring에서 Generic type 의 Bean을 Autowire하는 법?

@Configuration 클래스에서 autowired 할 필요가있는 bean Item 을 가지고 있습니다.

@Configuration
public class AppConfig {

    @Bean
    public Item<String> stringItem() {
        return new StringItem();
    }

    @Bean
    public Item<Integer> integerItem() {
        return new IntegerItem();
    }

}

하지만 @Autowire Item 을 사용하려고하면 다음 예외가 발생합니다.

"No qualifying bean of type [Item] is defined: expected single matching bean but found 2: stringItem, integerItem"

Spring에서 제네릭 타입 Item 을 어떻게 Autowire해야합니까?

해결법

  1. ==============================

    1.간단한 솔루션은 제네릭을 @Qualifier의 형태로 자동 고려하기 때문에 다음과 같이 스프링 4.0으로 업그레이드하는 것입니다.

    간단한 솔루션은 제네릭을 @Qualifier의 형태로 자동 고려하기 때문에 다음과 같이 스프링 4.0으로 업그레이드하는 것입니다.

    @Autowired
    private Item<String> strItem; // Injects the stringItem bean
    
    @Autowired
    private Item<Integer> intItem; // Injects the integerItem bean
    

    사실, 다음과 같이 목록에 삽입 할 때 중첩 제네릭을 autowire 할 수도 있습니다.

    // Inject all Item beans as long as they have an <Integer> generic
    // Item<String> beans will not appear in this list
    @Autowired
    private List<Item<Integer>> intItems;
    

    어떻게 작동합니까?

    새로운 ResolvableType 클래스는 실제로 제네릭 형식을 사용하는 논리를 제공합니다. 유형 정보를 쉽게 탐색하고 해결할 수 있습니다. ResolvableType의 대부분의 메소드는, ResolvableType를 돌려줍니다. 예를 들면 다음과 같습니다.

    // Assuming 'field' refers to 'intItems' above
    ResolvableType t1 = ResolvableType.forField(field); // List<Item<Integer>> 
    ResolvableType t2 = t1.getGeneric(); // Item<Integer>
    ResolvableType t3 = t2.getGeneric(); // Integer
    Class<?> c = t3.resolve(); // Integer.class
    
    // or more succinctly
    Class<?> c = ResolvableType.forField(field).resolveGeneric(0, 0);
    

    아래 링크에서 예제 및 자습서를 확인하십시오.

    희망이 당신을 도와줍니다.

  2. ==============================

    2.Spring 4로 업그레이드하고 싶지 않다면 다음과 같이 autowire를해야합니다 :

    Spring 4로 업그레이드하고 싶지 않다면 다음과 같이 autowire를해야합니다 :

    @Autowired
    @Qualifier("stringItem")
    private Item<String> strItem; // Injects the stringItem bean
    
    @Autowired
    @Qualifier("integerItem")
    private Item<Integer> intItem; // Injects the integerItem bean
    
  3. ==============================

    3.Spring autowired 전략은 설정 파일 (application.xml)에 정의되어있다.

    Spring autowired 전략은 설정 파일 (application.xml)에 정의되어있다.

    당신이 정의하지 않는다면, 디폴트는 타입에 의한 것이고, 스프링은 JDK 반영 메커니즘을 사용한다.

    List? String? 및 목록? 항목?, 형식이 동일한 List.class, 그래서 스프링 혼란 주입하는 방법입니다.

    그리고 위 사람 응답으로, 콩을 주사해야 봄을 알려주는 포인트 @ 품질해야합니다.

    Annotation보다는 Bean을 정의하기 위해 Spring 설정 파일을 좋아한다.

    <bean>
     <property name="stringItem">
            <list>
                  <....>
            </list>
     </property>
    

  4. ==============================

    4.Spring 4.0은 @Qualifier 주석 사용법에 대한 해답이다. 희망이 도움이

    Spring 4.0은 @Qualifier 주석 사용법에 대한 해답이다. 희망이 도움이

  5. ==============================

    5.나는 이것이 generics와 아무런 관련이 없다고 생각한다 ... 만약 당신이 동일한 타입의 두 개의 다른 bean을 주입한다면 Spring이 그들을 식별하는데 도움을 줄 수있는 한정어를 제공 할 필요가있다;

    나는 이것이 generics와 아무런 관련이 없다고 생각한다 ... 만약 당신이 동일한 타입의 두 개의 다른 bean을 주입한다면 Spring이 그들을 식별하는데 도움을 줄 수있는 한정어를 제공 할 필요가있다;

    ... 다른 곳

    @Configuration
    @Bean
    public Item stringItem() {
        return new StringItem();
    }
    
    @Bean
    public Item integerItem() {
        return new IntegerItem();
    }
    

    다음과 같은 비 generic 선언이있는 경우 Spring에서 이들을 식별 할 수 있도록 한정자를 추가해야합니다.

    @Autowired
    **@Qualifier("stringItem")**
    private Item item1;
    
    @Autowired
    **@Qualifier("integerItem")**
    private Item item2;
    

    물론 버전 4 이상에서는 스프링이 매우 멋지며 해결사를 통해 일반 유형을 고려합니다.

  6. from https://stackoverflow.com/questions/22603291/how-to-autowire-bean-of-generic-type-t-in-spring by cc-by-sa and MIT license