问题描述
我们可以为bean设置限定符名称(例如 @Qualifier(value =myBeanQualifiedName)
)。但我想知道如何在运行时在 @Configuration
类中设置限定符名称。
We can set qualifier names for a bean (for example @Qualifier(value="myBeanQualifiedName")
) . but I want to know how to set a Qualifier name at run time in a @Configuration
class.
假设基于应用程序逻辑,我想给bean一个名称作为配置文件中的限定符。
编辑:
Assume based on a application logic I want to give a name to a bean as a qualifier in a configuration file.
EDITED:
ConcreteBean是MyAbstractBean的子类。
ConcreteBean is a child class of 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将与使用它们的服务实例做不同的事情。
Assume getMySpecifiedBean() method is called from different locations and each location need difference instances, but the type of ConcretBean(). Instances are differ each other because of the setService() method set different property values. Therefore, the b1 and b2 will do difference things with its service instance where they are used.
在上面的示例中,根据条件,QUALIFIER_NAME名称将被更改。那么我们是否可以将准备好的QUALIFIER_NAME分配给新创建的bean的限定符名称?以及如何使用限定符名称获取此类bean(限定符名称已知)?例如,在另一个位置,
String qalifierName =QulifierName+ preparedConditionedString;
@Autowired
@Qualified(qalifierName)
In my above example, based on the condition, the QUALIFIER_NAME name will be changed.Then Can we assign the prepared QUALIFIER_NAME to the qualifier name to the newly created bean? and how to get such beans with the qualifier name (qualifier name is known) ? For example in another location,
String qalifierName="QulifierName" + preparedConditionedString;@Autowired@Qualified (qalifierName)
String qalifierName2 =QulifierName+ preparedConditionedString2;
@Autowired
@Qualified(qalifierName2)
String qalifierName2="QulifierName" + preparedConditionedString2;
@Autowired@Qualified (qalifierName2)
你也可以想一想,如果我们对限定符进行硬编码...但是想想如果要创建20个或更多个实例呢?我们必须重复这些代码。
Also you may think what if we hard code the qualifiers.. but think what if there 20 or more instances to be created ? We have to repeat the codes.
推荐答案
扩展我的看看ServiceLocatorFactoryBean评论:
Expanding on my "Have a look at ServiceLocatorFactoryBean" comment:
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映射到决策字符串(问题的核心功能)。
The IServiceFactory
InterfaceThis will allow you to map prototype beans to a decision string (core function of you question).
public interface IServiceFactory
{
IBean getNewInstance(String identifier);
}
IBean
接口
这将允许您从工厂处理返回的bean(原型)。
The IBean
InterfaceThis will allow you to handle the returned bean (prototype) from the factory.
public interface IBean
{
//TODO
}
IDecisionMaker
界面。
这将使您的决策制定流程不受工厂代码的限制。
实现采用条件
字符串并返回一个属性名称,该名称将从IServiceFactory实现/配置中生成一个IBean。
The IDecisionMaker
Interface.This will make your decision making processes independed of you factory code.An implementation takes your condition
string and returns a property name, that will result in a IBean from the IServiceFactory implementation/configuration.
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>
这篇关于如何在Spring中的运行时设置bean限定符名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!