Spring声明了多个bean

时间:2016-03-05 03:19:16

标签: java spring spring-bean

我有一个myobjects的HashMap,我想循环并将它们中的每一个声明为bean。最后,我想选择一个特定的键作为@primary。

有没有在Spring Java Config中执行此操作?

我无法在侦听器中执行此操作,因为在上下文加载时需要这些bean。我正在看工厂豆,但无法弄明白。

感谢任何帮助。

由于 ABHI

1 个答案:

答案 0 :(得分:0)

您可以通过在一个Java配置类中获取对ApplicationContext的引用来创建一组bean。例如,

@Configuration
public class ServicesConfig {

    @PostConstruct
    public void onPostConstruct() {
       Map<String, MyClass> mapOfClasses = HashMap<>(); // your HashMap of objects
       AutowireCapableBeanFactory autowireCapableBeanFactory = context.getAutowireCapableBeanFactory();
       BeanDefinitionRegistry registry = (BeanDefinitionRegistry) autowireCapableBeanFactory;

       for (Map.Entry<String, MyClass> myClassEntry : mapOfClasses.entrySet()) {
         GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
         beanDefinition.setBeanClass(myClassEntry.getValue().getClass());
         beanDefinition.setAutowireCandidate(true);
         registry.registerBeanDefinition(myClassEntry.getKey(), beanDefinition);
         autowireCapableBeanFactory.autowireBeanProperties(myClassEntry,
                AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
       }
    }
}

此处MyClassmyobject的类型,每个MyClass也可以有@Autowired个注释。此时,我假设这些对象中的每一个都将被赋予其bean名称HashMap的密钥。如果需要,这个对象可以用作其他bean的依赖项。

通过实施BeanDefinitionRegistryPostProcessor并覆盖postProcessBeanDefinitionRegistry来注册HashMap个对象,可以实现同样的目的。在此方法中,您可以使用BeanDefinition创建BeanDefinitionBuilder

AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(MyClass.class).getBeanDefinition();
beanDefinitionRegistry.registerBeanDefinition("key_of_this_object", beanDefinition);

我不确定你是否可以将其中一个bean标记为@Primary。但基于此post,您可以通过扩展我自己未经过测试的DefaultListableBeanFactory来定义自己的bean解析器。作为替代方案,您可以使用@Qualifier,因为您已经知道哪个对象将成为主要bean。

希望这会有所帮助。

P.S如果对象已经可以添加到ApplicationContext中,则以下方法会将这些自定义对象添加到ApplicationContext

ConfigurableListableBeanFactory configurableListableBeanFactory = ((ConfigurableApplicationContext)context).getBeanFactory();
configurableListableBeanFactory.registerSingleton("key_of_this_object", myClassObject);