Tak, można zrobić to z pomocą swojej niestandardowej implementacji BeanFactoryPostProcessor.
Oto prosty przykład.
Załóżmy, że mamy dwa elementy. Jednym z nich jest zależność dla drugiego.
Pierwszy składnik:
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;
}
}
Jak można zobaczyć, nie ma nic szczególnego w tym składnikiem. Ma zależność od dwóch różnych instancji MySecondComponent.
Drugi komponent:
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;
}
}
To trochę bardziej skomplikowane. Oto dwie rzeczy do wyjaśnienia. Pierwszy - @Qualifier - adnotacja, która zawiera nazwy komponentów bean MySecondComponent. Jest to standardowa, ale możesz zaimplementować własną. Zobaczysz nieco później, dlaczego.
Drugą rzeczą, o której warto wspomnieć, jest wdrożenie FactoryBean. Jeśli komponent bean implementuje ten interfejs, ma on na celu utworzenie kilku innych instancji. W naszym przypadku tworzy wystąpienia z typem MySecondComponent.
Najtrudniejsza część jest realizacja 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(",");
}
}
Co on robi? Przechodzi przez wszystkie fasole opatrzone komentarzem @Qualifier, wyodrębnia nazwy z adnotacji, a następnie ręcznie tworzy fasole tego typu o określonych nazwach.
Oto Wiosna config:
<?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>
Ostatnią rzeczą, aby zauważyć tutaj jest chociaż może zrobić to ty nie powinny chyba że jest to konieczne, ponieważ jest to naprawdę nie sposób naturalny konfiguracji. Jeśli masz więcej niż jedną instancję klasy, lepiej trzymać się konfiguracji XML.
Nie sądzę, że możesz. '@ Component' jest lekką wygodą, ale nie zastępuje konfiguracji XML. – skaffman
Myślę, że szkoda, że XML jest uważany za właściwy sposób konfigurowania aplikacji. –
To, że '@ Component' nie może tego zrobić, nie oznacza, że XML jest rozwiązaniem. Nie wiem o 2011 r., Ale można uzyskać ten sam efekt w java '@ Configuration". – apottere