Oui, vous pouvez le faire avec l'aide de votre implémentation BeanFactoryPostProcessor personnalisée.
Voici un exemple simple.
Supposons que nous ayons deux composants. L'un est la dépendance pour l'autre.
Première composante:
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;
}
}
Comme vous pouvez le voir, il n'y a rien de spécial sur ce composant. Il dépend de deux instances différentes de MySecondComponent.
Deuxième composante:
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;
}
}
Il est un peu plus délicat. Voici deux choses à expliquer. Premier - @Qualifier - annotation qui contient les noms des beans MySecondComponent. C'est un standard, mais vous êtes libre de mettre en place le vôtre. Vous verrez un peu plus tard pourquoi.
La deuxième chose à mentionner est l'implémentation FactoryBean. Si bean implémente cette interface, il est prévu de créer d'autres instances. Dans notre cas, il crée des instances avec le type MySecondComponent.
La partie la plus délicate est la mise en œuvre 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(",");
}
}
Que faut-il faire? Il passe en revue tous les beans annotés avec @Qualifier, extrait les noms de l'annotation, puis crée manuellement des beans de ce type avec des noms spécifiés.
Voici une configuration Spring:
<?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>
La dernière chose à remarquer ici est bien que vous pouvez le faire vous ne devrait pas à moins qu'il est indispensable, parce que c'est un moyen pas vraiment naturel de configuration. Si vous avez plusieurs instances de classe, il est préférable de s'en tenir à la configuration XML.
Je ne pense pas que vous le pouvez. '@ Component' est une commodité légère, mais pas de substitut pour la config XML. – skaffman
Je pense qu'il est regrettable que XML soit considéré comme le bon moyen de configurer une application. –
Ce n'est pas parce que '@ Component' ne le peut pas que XML est la solution. Je ne sais pas à propos de 2011, mais vous pouvez obtenir le même effet dans un 'Java Configuration' juste maintenant. – apottere