我们可以为bean设置限定符名称(例如@Qualifier(value="myBeanQualifiedName")
)。但我想知道如何在@Configuration
课程中的运行时设置限定符名称。
假设基于应用程序逻辑,我想给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(限定符名称已知)?例如,在另一个位置,
String qalifierName =" QulifierName" + preparedConditionedString;
@Autowired
@Qualified(qalifierName)
String qalifierName2 =" QulifierName" + preparedConditionedString2;
@Autowired
@Qualified(qalifierName2)
你也可以想一想,如果我们对限定符进行硬编码,那么想想如果要创建20个或更多个实例呢?我们必须重复这些代码。
答案 0 :(得分: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
界面
这将允许您将原型bean映射到决策字符串(您的问题的核心功能)。
public interface IServiceFactory
{
IBean getNewInstance(String identifier);
}
IBean
界面
这将允许您从工厂处理返回的bean(原型)。
public interface IBean
{
//TODO
}
IDecisionMaker
界面。
这将使您的决策制定流程不受工厂代码的限制。
实现采用您的condition
字符串并返回一个属性名称,该名称将从IServiceFactory实现/配置中生成一个IBean。
public interface IDecisionMaker
{
String decide(String condition);
}
Spring 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>