2014-08-31 4 views
3

빈에 대한 한정자 이름을 설정할 수 있습니다 (예 : @Qualifier(value="myBeanQualifiedName")). 하지만 런타임에 한정자 이름을 @Configuration 클래스로 설정하는 방법을 알고 싶습니다.Spring에서 런타임에 빈 한정자 이름을 설정하는 방법

응용 프로그램 논리를 기반으로한다고 가정합니다. 구성 파일의 한정자로 bean에 이름을 지정하려고합니다.
편집 :

ConcreteBean는 MyAbstractBean의 하위 클래스입니다.

@Configuration 
public class MyBeanFactory { 

    @Bean 
    public MyAbstractBean getMySpecifiedBean(String condition){ 
     String QUALIFIER_NAME="QulifierName"+condition; 
     if(//some condition here){ 
     //How to set a qualifier name :QUALIFIER_NAME for this ConcreteBean instance?  
     MyAbstractBean b1= new ConcreteBean(); 
     b1.setService(new AnotherService1); // and set some field values to this concrete bean 
     return b1; 
     } 
     else { 
     MyAbstractBean b2= new ConcreteBean(); 
     b2.setService(new AnotherService2); 
     return b2; 
     } 

    } 
} 

는 방법은 다른 위치()를 호출 getMySpecifiedBean을 가정하고 각 위치 차이 인스턴스 필요하지만 ConcretBean 유형(). setService() 메서드가 다른 속성 값을 설정했기 때문에 인스턴스가 서로 다릅니다. 따라서 b1과 b2는 사용되는 서비스 인스턴스와 다른 점을 수행합니다.

위의 예에서 조건에 따라 QUALIFIER_NAME 이름이 변경됩니다. 그런 다음 준비된 QUALIFIER_NAME을 (를) 한정자 이름에 새로 생성 된 bean에 할당 할 수 있습니까? 한정자 이름 (한정자 이름이 알려져 있음)이있는 bean을 얻는 방법은 무엇입니까? 예를 들어 다른 위치에서
문자열 qalifierName = "QulifierName"+ preparedConditionedString; @Autowired @Qualified (qalifierName)

문자열 qalifierName2 = "QulifierName"+ preparedConditionedString2;
@Autowired @Qualified (qalifierName2)

은 또한 당신이 만약에 우리가 하드 코드 예선 .. 생각하지만, 거기에 20 개 이상의 인스턴스를 생성 할 경우 어떻게 생각? 코드를 반복해야합니다.

+0

?또한 bean을 올바르게 작성한 경우, 규정 자에 대한 관심은 어떨까요? – geoand

+1

ServiceLocatorFactoryBean – Hannes

+0

@geoand를 살펴보십시오. 조건에 따라 빈에 설정된 매개 변수가 달라질 수 있다고 가정합니다. 이것은 공장 패턴과 같을 수 있습니다. 또한 매개 변수 값을 기반으로 Bean이 사용중인 경우 Bean의 기능은 다른 Bean과 다를 수 있습니다. 그러므로 올바른 빈을 얻는 것이 중요합니다. –

답변

3

내 "ServiceLocatorFactoryBean에서보세요"코멘트에 확장 :이 (당신이 질문의 핵심 기능) 당신이 결정 문자열로 프로토 타입 빈을 매핑 할 수

public class MyBeanFactory 
{ 
    private IServiceFactory serviceFactory; 
    private IDecisionMaker decisionMaker; 

    public IBean createNewInstance(final String condition) 
    { 
     String conditionResult = decisionMaker.decide(condition); 
     return serviceFactory.getNewInstance(conditionResult); 
    } 

    public void setServiceFactory(final IServiceFactory serviceFactory) 
    { 
     this.serviceFactory = serviceFactory; 
    } 
    public void setDecisionMaker(final IDecisionMaker decisionMaker) 
    { 
     this.decisionMaker = decisionMaker; 
    } 
} 

IServiceFactory 인터페이스.

public interface IServiceFactory 
{ 
    IBean getNewInstance(String identifier); 
} 

은이 당신이 공장에서 반환 된 콩 (프로토 타입)을 처리 할 수 ​​ IBean 인터페이스.

public interface IBean 
{ 
    //TODO 
} 

IDecisionMaker 인터페이스

. 이렇게하면 의사 결정 프로세스가 공장 코드와 무관하게됩니다. 구현시 condition 문자열이 사용되며 속성 이름이 반환되므로 IServiceFactory 구현/구성의 IBean이됩니다.

public interface IDecisionMaker 
{ 
    String decide(String condition); 
} 

스프링 XML Konfiguration 우리가 얘기하는 조건의 어떤 종류의

<! implementations of the IBean interface --> 
<bean id="myBeanRed" class="..." scope="prototype" /> 
<bean id="myBeanBlue" class="..." scope="prototype" /> 
<bean id="myBeanGreen" class="..." scope="prototype" /> 

<!-- the decision maker --> 
<bean id="decisionMaker" class="..."> 
     <!-- define your decision making here like: 
      condition(color=red)->red 
      condition(color=blue)->blue 
      condition(ELSE)->green 
     --> 
</bean> 

<!-- the abstract factory --> 
<bean id="myBeanServiceFactory" class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean"> 
    <property name="serviceLocatorInterface" value="...IServiceFactory "/> 
    <property name="serviceMappings"> 
     <props> 
      <prop key="red">myBeanRed</prop> 
      <prop key="blue">myBeanBlue</prop> 
      <prop key="green">myBeanGreen</prop> 
     </props> 
    </property> 
</bean> 

<!-- the factory --> 
<bean id="myBeanFac" class="...MyBeanFactory" scope="singleton"> 
    <property name="serviceFactory" ref="myBeanServiceFactory" /> 
    <property name="decisionMaker" ref="decisionMaker" /> 
</bean> 
+0

귀하의 지원에 감사 드리며 자세한 샘플을 보내 주셔서 대단히 감사합니다. –

관련 문제