source

봄에 일반 타입의 빈 오토와이어는?

manysource 2022. 11. 23. 20:22

봄에 일반 타입의 빈 오토와이어는?

나는 콩이 있다.Item<T>자동 배선이 필요합니다.@Configuration학급.

@Configuration
public class AppConfig {

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

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

}

하지만 내가 하려고 할 때론@Autowire Item<String>, 다음과 같은 예외가 있습니다.

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

일반 유형을 자동 배선하는 방법Item<T>봄에?

간단한 해결책은 Spring 4.0으로 업그레이드하는 것입니다.Spring 4.0은 범용 기능을 자동으로@Qualifier이하와 같습니다.

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

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

목록에 삽입할 때 다음과 같이 중첩된 제네릭을 자동 연결할 수도 있습니다.

// 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예를 들어 다음과 같습니다.

// 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);

아래 링크에서 예시와 튜토리얼을 확인하십시오.

도움이 되시길 바랍니다.

Spring 4로 업그레이드하지 않을 경우 다음과 같이 이름으로 자동 배선해야 합니다.

@Autowired
@Qualifier("stringItem")
private Item<String> strItem; // Injects the stringItem bean

@Autowired
@Qualifier("integerItem")
private Item<Integer> intItem; // Injects the integerItem bean

이 질문에 답하기 위해 제가 만든 솔루션은 다음과 같습니다.


        List<String> listItem= new ArrayList<>();

        ResolvableType resolvableType = ResolvableType.forClassWithGenerics(List.class, String.class);
        RootBeanDefinition beanDefinition = new RootBeanDefinition();
        beanDefinition.setTargetType(resolvableType);
        beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
        beanDefinition.setAutowireCandidate(true);

        DefaultListableBeanFactory bf = (DefaultListableBeanFactory) configurableWebApplicationContext.getBeanFactory();

        bf.registerBeanDefinition("your bean name", beanDefinition);
        bf.registerSingleton("your bean name", listItem);

스프링 자동 배선 전략은 컨피규레이션파일(application.xml)에 정의되어 있습니다.

정의하지 않은 경우 기본값은 유형별이며 스프링 주입은 JDK 리플렉트 메커니즘을 사용합니다.

그래서 리스트?스트링? 리스트?아이템? 타입이 List.class라서 스프링이 주입하는 방법을 헷갈렸습니다.

그리고 위의 답변과 같이 어떤 콩을 주입해야 하는지 스프링에 알려주려면 포인트 @Qualifier가 되어야 합니다.

주석보다는 빈을 정의하는 스프링 구성 파일이 좋습니다.

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

Spring 4.0은 @Qualifier 주석 사용에 대한 답변입니다.도움이 되었으면 좋겠다

제네릭과는 아무 관련이 없는 것 같은데...같은 타입의 두 개의 다른 콩을 주입하는 경우 스프링이 그것들을 식별할 수 있도록 한정자를 제공해야 합니다.

...기타

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

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

이와 같은 일반적이지 않은 선언이 있는 경우 스프링이 식별하기 위해 한정자를 추가해야 합니다.

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

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

물론 버전 4 이상의 봄에서는 범용 타입을 리졸버를 통해 고려합니다.이것은 매우 쿨합니다.

언급URL : https://stackoverflow.com/questions/22603291/how-to-autowire-bean-of-generic-type-t-in-spring