Sì, lo si può fare con l'aiuto della tua implementazione personalizzata BeanFactoryPostProcessor.
Ecco un semplice esempio.
Supponiamo di avere due componenti. Uno è dipendenza per un altro.
Prima componente:
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
public class MyFirstComponent implements InitializingBean{
private MySecondComponent asd;
private MySecondComponent qwe;
public void afterPropertiesSet() throws Exception {
Assert.notNull(asd);
Assert.notNull(qwe);
}
public void setAsd(MySecondComponent asd) {
this.asd = asd;
}
public void setQwe(MySecondComponent qwe) {
this.qwe = qwe;
}
}
Come si può vedere, non c'è niente di speciale in questo componente. Ha dipendenza da due diverse istanze di MySecondComponent.
Seconda componente:
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
@Qualifier(value = "qwe, asd")
public class MySecondComponent implements FactoryBean {
public Object getObject() throws Exception {
return new MySecondComponent();
}
public Class getObjectType() {
return MySecondComponent.class;
}
public boolean isSingleton() {
return true;
}
}
E 'un po' più complicato. Qui ci sono due cose da spiegare. Il primo - @Qualifier - annotazione che contiene i nomi dei bean MySecondComponent. È uno standard, ma sei libero di implementare il tuo. Vedrai un po 'più tardi perché.
La seconda cosa da menzionare è l'implementazione di FactoryBean. Se il bean implementa questa interfaccia, è prevista la creazione di altre istanze. Nel nostro caso crea istanze con tipo MySecondComponent.
La parte più difficile è la realizzazione BeanFactoryPostProcessor:
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
Map<String, Object> map = configurableListableBeanFactory.getBeansWithAnnotation(Qualifier.class);
for(Map.Entry<String,Object> entry : map.entrySet()){
createInstances(configurableListableBeanFactory, entry.getKey(), entry.getValue());
}
}
private void createInstances(
ConfigurableListableBeanFactory configurableListableBeanFactory,
String beanName,
Object bean){
Qualifier qualifier = bean.getClass().getAnnotation(Qualifier.class);
for(String name : extractNames(qualifier)){
Object newBean = configurableListableBeanFactory.getBean(beanName);
configurableListableBeanFactory.registerSingleton(name.trim(), newBean);
}
}
private String[] extractNames(Qualifier qualifier){
return qualifier.value().split(",");
}
}
Che cosa fa? Passa attraverso tutti i bean annotati con @Qualifier, estrae i nomi dall'annotazione e quindi crea manualmente i bean di questo tipo con nomi specifici.
Ecco una configurazione Primavera:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="MyBeanFactoryPostProcessor"/>
<bean class="MySecondComponent"/>
<bean name="test" class="MyFirstComponent">
<property name="asd" ref="asd"/>
<property name="qwe" ref="qwe"/>
</bean>
</beans>
Ultima cosa da notare qui è anche se si può farlo si non dovrebbe meno che non si è d'obbligo, perché questo è un modo non proprio naturale di configurazione. Se hai più di un'istanza di classe, è meglio attenersi alla configurazione XML.
Non penso che tu possa. '@ Componente' è una comodità leggera, ma non sostituisce la configurazione XML. – skaffman
Penso sia deplorevole che XML sia considerato il modo corretto di configurare un'applicazione. –
Solo perché '@ Component' non può farlo, non significa che XML sia la soluzione. Non so il 2011, ma ora puoi ottenere lo stesso effetto in una 'configurazione @ java '. – apottere