복붙노트

[SPRING] Spring에서 조건부 자동 배선을 수행하는 방법은 무엇입니까?

SPRING

Spring에서 조건부 자동 배선을 수행하는 방법은 무엇입니까?

누군가가 조건에 따라 다른 bean을 Spring 관리 bean으로 자동 연결하려고 시도 했습니까? 예 : 어떤 조건이 충족되면 클래스 A를 주입하고 그렇지 않으면 B? Google 검색 결과 중 하나에서 SpEL (Spring Expression Language)에서 가능하지만 작동 예제를 찾을 수 없다는 것을 알았습니다.

해결법

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

    1.이것을 달성하는 방법은 여러 가지가 있습니다. 대부분 이것은 수행하려는 컨디셔닝에 따라 다릅니다.

    이것을 달성하는 방법은 여러 가지가 있습니다. 대부분 이것은 수행하려는 컨디셔닝에 따라 다릅니다.

    조건부 배선을하기 위해 간단한 factory bean을 구현할 수 있습니다. 이러한 factory bean은 복잡한 조절 로직을 포함 할 수 있습니다 :

    public MyBeanFactoryBean implements FactoryBean<MyBean> {
    
        // Using app context instead of bean references so that the unused 
        // dependency can be left uninitialized if it is lazily initialized
        @Autowired
        private ApplicationContext applicationContext;
    
        public MyBean getObject() {
            MyBean myBean = new MyBean();
            if (true /* some condition */) {
                myBean.setDependency(applicationContext.getBean(DependencyX.class));
            } else {
                myBean.setDependency(applicationContext.getBean(DependencyY.class));
            }
            return myBean;
        }
    
        // Implementation of isSingleton => false and getObjectType
    
    }
    

    어쩌면 좀 더 나은 접근법은 응용 프로그램 컨텍스트에서 하나의 bean 만 가지기를 원한다면 factory bean을 사용하여 종속성 bean을 작성하는 것입니다.

    public MyDependencyFactoryBean implements FactoryBean<MyDependency> {
    
        public MyDependency getObject() {
            if (true /* some condition */) {
                return new MyDependencyX();
            } else {
                return new MyDependencyY();
            }
        }
    
        // Implementation of isSingleton => false and getObjectType
    
    }
    

    SpEL에는 많은 가능성이 있습니다. 가장 일반적으로 사용되는 시스템 속성 기반 조건은 다음과 같습니다.

    <bean class="com.example.MyBean">
        <property name="dependency" value="#{systemProperties['foo'] == 'bar' ? dependencyX : dependencyY}" />
    </bean>
    

    bean 플레이 백을 프로퍼티 플레이스 홀더로 해결할 수 있습니다. 종속성 이름은 응용 프로그램 구성의 일부일 수 있습니다.

    <bean class="com.example.MyBean">
        <property name="dependency" ref="${dependencyName}" />
    </bean>
    

    일반적으로 평가하고자하는 조건은 콩의 전체 집합이 등록되어 있거나 등록되어서는 안된다는 것을 의미합니다. 이것을 위해 스프링 프로파일을 사용할 수 있습니다 :

    <!-- Default dependency which is referred by myBean -->
    <bean id="dependency" class="com.example.DependencyX" />
    
    <beans profile="myProfile">
        <!-- Override `dependency` definition if myProfile is active -->
        <bean id="dependency" class="com.example.DependencyY" />
    </beans>
    

    다른 메소드는 bean 정의를 lazy-init = "true"로 표시 할 수 있지만 정의는 응용 프로그램 컨텍스트 내에서 계속 등록됩니다 (그리고 정규화되지 않은 autowiring을 사용할 때 더 힘들게 만듭니다). @Profile 주석을 통해 @Component 기반 Bean과 함께 프로파일을 사용할 수도 있습니다.

    ApplicationContextInitializer (또는이 예제)를 검사하여 프로필을 프로그래밍 방식으로 활성화하는 방법 (즉, 조건에 따라)을 확인하십시오.

    자바 기반 설정이 그렇게 인기가있는 이유는 다음과 같습니다.

    @Bean
    public MyBean myBean() {
        MyBean myBean = new MyBean();
        if (true /* some condition */) {
            myBean.setDependency(dependencyX());
        } else {
            myBean.setDependency(dependencyY());
        }
        return myBean;
    }
    

    물론 자바 기반 설정에서도 @Profile, @Value 또는 @Qualifier + @Autowired를 통해 더 많거나 적은 모든 설정 메소드를 사용할 수 있습니다.

    Spring은 애플리케이션 컨텍스트 라이프 사이클에 참여할 수있는 다양한 후크 포인트 및 SPI를 제공합니다. 이 섹션에서는 Spring의 내부 동작에 대한 좀 더 많은 지식이 필요합니다.

    BeanFactoryPostProcessors는 빈 정의를 읽고 변경할 수 있습니다 (예 : 속성 자리 표시 자 $ {}가이 방법으로 구현 됨).

    BeanPostProcessors는 Bean 인스턴스를 처리 할 수 ​​있습니다. 새로 만든 빈을 확인하고 그와 함께 플레이 할 수 있습니다 (예 : @Scheduled 주석 처리가 이렇게 구현됩니다).

    MergedBeanDefinitionPostProcessor는 bean post processor의 확장이며, 인스턴스화되기 직전에 bean 정의를 변경할 수 있습니다 (@Autowired annotation 처리가 이렇게 구현됩니다).

    2015 년 10 월 업데이트

  2. from https://stackoverflow.com/questions/19225115/how-to-do-conditional-auto-wiring-in-spring by cc-by-sa and MIT license