问题
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.
Assume based on a application logic I want to give a name to a bean as a qualifier in a configuration file.
EDITED:
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;
}
}
}
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.
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)
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.
回答1:
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;
}
}
The IServiceFactory
Interface
This will allow you to map prototype beans to a decision string (core function of you question).
public interface IServiceFactory
{
IBean getNewInstance(String identifier);
}
The IBean
Interface
This will allow you to handle the returned bean (prototype) from the factory.
public interface IBean
{
//TODO
}
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);
}
The 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>
来源:https://stackoverflow.com/questions/25590435/how-to-set-a-bean-qualifier-name-at-run-time-in-spring