복붙노트

[SPRING] 유형별 스프링 목록 빈

SPRING

유형별 스프링 목록 빈

Spring에 모든 유형의 빈과 모든 하위 유형이있는 목록을 자동으로 채울 수있는 방법이 있습니까? 다음과 같은 setter 메서드가 있습니다.

setMyProp(List<MyType> list)

MyType의 모든 빈과 MyType의 모든 하위 클래스에서 autowire를하고 싶습니다.

감사, 제프

해결법

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

    1.네, 할 수 있어요. 스프링 워드 프로세서는 다음과 같이 말합니다.

    네, 할 수 있어요. 스프링 워드 프로세서는 다음과 같이 말합니다.

    목록이 아니라 배열을 기대해야한다는 것을 명심하십시오. generic type erasure는 런타임에 목록이 작동하지 않을 수도 있기 때문에 의미가 있습니다. 그러나 작동하는 다음 단원 테스트를 수행하십시오.

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">  
    
        <bean class="test.Test.TypeB"/>
        <bean class="test.Test.TypeC"/>
        <bean class="test.Test.TypeD"/>
    </beans>
    

    이 단위 테스트 :

    package test;
    
    @ContextConfiguration
    @RunWith(SpringJUnit4ClassRunner.class)
    public class Test {
    
        private @Autowired List<TypeA> beans;
    
        @org.junit.Test
        public void test() {
            assertNotNull(beans);
            assertEquals(2, beans.size());
            for (TypeA bean : beans) {
                assertTrue(bean instanceof TypeA);
            }
        }       
    
        public static interface TypeA {}
        public static class TypeB implements TypeA {}
        public static class TypeC extends TypeB {}
        public static class TypeD {}
    
    }
    

    그래서 공식적으로 ListA 가 아닌 TypeA []를 자동으로 실행해야합니다. 그러나 목록은 잘 작동합니다.

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

    2.Bean 정의 파일 내에서가 아니라 애플리케이션 코드에서 목록을 채우는 것이 허용되면 org.springframework.beans.factory.xml.XmlBeanFactory를 사용하여 "getBeansOfType (MyType.class)"라고 질문 할 수있다. 이렇게하면 MyType의 유형 (및 부속 유형)의 모든 bean이 제공됩니다.

    Bean 정의 파일 내에서가 아니라 애플리케이션 코드에서 목록을 채우는 것이 허용되면 org.springframework.beans.factory.xml.XmlBeanFactory를 사용하여 "getBeansOfType (MyType.class)"라고 질문 할 수있다. 이렇게하면 MyType의 유형 (및 부속 유형)의 모든 bean이 제공됩니다.

  3. ==============================

    3.@Autowired를 코드 내부에 사용할 수 있으면 skaffman이 언급 한 방법을 안전하게 사용할 수 있습니다. XML 설정을 고집한다면, 이것을 달성하기 위해 Hera라는 작은 라이브러리가 있습니다. 기본적으로 시나리오의 구성은 다음과 같습니다.

    @Autowired를 코드 내부에 사용할 수 있으면 skaffman이 언급 한 방법을 안전하게 사용할 수 있습니다. XML 설정을 고집한다면, 이것을 달성하기 위해 Hera라는 작은 라이브러리가 있습니다. 기본적으로 시나리오의 구성은 다음과 같습니다.

    <bean id="client" class="..">
        <property name="injectDynamicListHere">
            <hera:list class="my.custom.SuperType" />
        </property>
    </bean>
    

    이것은 List로 SuperType을 구현하는 모든 최상위 Spring 빈을 클라이언트 빈에 주입 할 것이다.

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

    4.짧은 대답 : 아니오.

    짧은 대답 : 아니오.

    긴 대답 : Java generics는 형식 지움에 의해 작동합니다. 즉, 런타임에 매개 변수가 단순한 목록이고 일반 형식의 목록이 아니라는 것을 의미합니다. 따라서 매개 변수 유형 MyType이기 때문에이 동작을 구현할 수 없다는 것을 알 수 없습니다.

    즉, 이렇게하는 다른 방법이 있습니다. 가장 명백한 것은 bean 생성을 기다린 다음 MyType (또는 하위 클래스)인지 확인한 다음 참조를 유지하는 것입니다.

    이를 수행하는 데는 몇 가지 방법이있을 수 있습니다. 하나는 bean post-processor를 만드는 것이다. 이렇게하면 생성 된 모든 빈에 대한 알림을 받게됩니다.

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

    5.레거시 코드 및 누락 된 @Autowired로 인해 나는 그것을 해결 :

    레거시 코드 및 누락 된 @Autowired로 인해 나는 그것을 해결 :

    MyBean implements ApplicationContextAware{
    
      @Override
      public void setApplicationContext(ApplicationContext ctx) throws BeansException {
        final Map<String, HttpRequestHandlerTemplate> beansOfType = ctx.getBeansOfType(RequiredBean.class);
        ...
    }
    
  6. from https://stackoverflow.com/questions/1450145/spring-list-beans-by-type by cc-by-sa and MIT license