codememo

봄에 조건부 자동 배선을 어떻게 하나요?

tipmemo 2023. 7. 27. 22:01
반응형

봄에 조건부 자동 배선을 어떻게 하나요?

조건에 따라 다른 콩을 스프링 관리 콩으로 자동 배선하려고 시도한 사람이 있습니까?예를 들어 어떤 조건이 충족되면 클래스 A를 주입하고 그렇지 않으면 B를 주입합니다.구글 검색 결과 중 하나에서 봄 표현 언어(SpEL)로 가능하다는 것을 보았지만, 작동 예시를 찾을 수 없었습니다.

이를 달성하는 방법은 여러 가지가 있습니다.대부분 수행하려는 조건에 따라 달라집니다.

팩토리빈

조건부 배선을 위해 간단한 공장 빈을 구현할 수 있습니다.이러한 공장 원두에는 다음과 같은 복잡한 조건화 논리가 포함될 수 있습니다.

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

}

애플리케이션 컨텍스트에서 이러한 빈을 하나만 사용하려는 경우 팩토리 빈을 사용하여 종속 빈을 생성하는 것이 더 나은 방법일 수 있습니다.

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

다른 방법은 빈 정의를 다음과 같이 표시할 수 있습니다.lazy-init="true"그러나 정의는 여전히 애플리케이션 컨텍스트 내에 등록됩니다(무자격 자동 배선을 사용할 경우 사용자의 삶이 더 어려워집니다).프로파일을 다음과 같이 사용할 수도 있습니다.@Component베이스 원두.@Profile주석

사용자의 상태에 따라 프로파일을 프로그래밍적으로 활성화하는 방법을 보려면(또는 이 예를) 선택합니다.

자바 구성

이러한 이유로 Java 기반 구성이 인기를 끌고 있습니다.

@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의 내부 작동에 대한 지식이 필요합니다.

BeanFactoryPostProcessor스캔은 빈 정의를 읽고 변경합니다(예: 속성 자리 표시자).${}해결 방법은 이 방법으로 구현됩니다.

BeanPostProcessor스캔 프로세스 빈 인스턴스. 노는 합니다( 생된콩예확가고노것가지다능니합이는고하인을성로새예▁and(:▁it다니▁with가합능:@Scheduled주석 처리는 이러한 방식으로 구현됩니다.

MergedBeanDefinitionPostProcessor빈 포스트 프로세서의 확장이며 인스턴스화되기 직전에 빈 정의를 변경할 수 있습니다(@Autowired주석 처리는 이러한 방식으로 구현됩니다.


2015년 10월 업데이트

  • 스프링 4는 주석을 통한 조건부 빈 등록을 수행하는 새로운 방법을 추가했습니다.그것도 확인할 가치가 있습니다.

  • 는 봄부트를 만 사용할 수 있는 여러 가지 방법이 있습니다.@ConditionalOn*.

  • 또한 두 가지 모두에 유의하십시오.@Import그리고.@ComponentScan 해당 대응물은 속성 ("XML")을 할 수 .)${}).

@Configuration 클래스에서 조건부로 생성할 빈을 선언합니다.

@Bean
@Conditional(CustomFeatureCondition.class)
public Stuff stuff() {
    return new Stuff ();
}

필수 = false 옵션과 함께 @Autowire만 사용하는 경우:

@Component
@Setter(onMethod_ = @Autowired(required = false))
public class AnotherStuff {
    private Stuff stuff;
    // do stuff here
}

이렇게 하면 컨텍스트에 Stuffbean이 있으면 Stuffbean을 얻을 수 있고 그렇지 않으면 stuff= null을 얻을 수 있습니다.

저는 속성에 따라 다른 콩을 주입해야 하는 경우가 있었습니다: "my.property".저의 경우 이 솔루션은 성공적이었습니다.

 <property name="name" ref="#{ ${my.property:false}==true ? 'bean1' : 'bean2' }"/>

콩 이름 주위에 아포스트로피를 붙여야 제대로 작동할 수 있었습니다.

가장 간단한 방법은:

@Autowired @Lazy
protected A a;

@Autowired @Lazy
protected B b;

void do(){
  if(...) { // any condition
     // use a
  } else {
     // use b
  }
}

bean을 경우, 에 "Spring"을 던집니다.NoSuchBeanDefinitionException

언급URL : https://stackoverflow.com/questions/19225115/how-to-do-conditional-auto-wiring-in-spring

반응형