Да, вы можете сделать это с помощью собственной реализации BeanFactoryPostProcessor.
Вот простой пример.
Предположим, у нас есть два компонента. Одно зависит от другого.
Первый компонент:
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;
}
}
Как видите, ничего особенного в этом компоненте нет. Он зависит от двух разных экземпляров MySecondComponent.
Второй компонент:
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;
}
}
Это немного сложнее. Вот две вещи, которые нужно объяснить. Первый — @Qualifier — аннотация, содержащая имена bean-компонентов MySecondComponent. Он стандартный, но вы можете реализовать свой собственный. Чуть позже вы увидите, почему.
Второе, что следует упомянуть, это реализация FactoryBean. Если компонент реализует этот интерфейс, он предназначен для создания некоторых других экземпляров. В нашем случае он создает экземпляры с типом MySecondComponent.
Самая сложная часть — реализация 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(",");
}
}
Что оно делает? Он проходит через все bean-компоненты, аннотированные @Qualifier, извлекает имена из аннотации, а затем вручную создает bean-компоненты этого типа с указанными именами.
Вот конфигурация 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>
Последнее, на что следует обратить внимание, это то, что хотя вы можете сделать это, вы не должны делать это, если только это не является обязательным, потому что это не совсем естественный способ настройки. Если у вас более одного экземпляра класса, лучше придерживаться конфигурации XML.
person
wax
schedule
25.05.2010
@Component
— это легкое удобство, но оно не заменяет конфигурацию XML. - person skaffman   schedule 25.05.2010@Component
не может этого сделать, не означает, что XML является решением. Я не знаю насчет 2011 года, но сейчас вы можете добиться того же эффекта в java@Configuration
. - person apottere   schedule 24.03.2017