How to instantiate spring managed beans at runtime?

后端 未结 5 1148
野的像风
野的像风 2020-12-02 11:24

I stuck with a simple refactoring from plain java to spring. Application has a \"Container\" object which instantiates its parts at runtime. Let me explain with the code:

5条回答
  •  清歌不尽
    2020-12-02 12:04

    It is possible to register beans dynamically by using BeanFactoryPostProcesor. Here you can do that while application is booting (spring's application context is beeing initialized). You can not register beans latet, but on the other hand you can make use of dependency injection for your beans, as they become "true" Spring beans.

    public class DynamicBeansRegistar implements BeanFactoryPostProcessor {
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            if (! (beanFactory instanceof BeanDefinitionRegistry))  {
                throw new RuntimeException("BeanFactory is not instance of BeanDefinitionRegistry);
            }   
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    
            // here you can fire your logic to get definition for your beans at runtime and 
            // then register all beans you need (possibly inside a loop)
    
            BeanDefinition dynamicBean = BeanDefinitionBuilder.    
                 .rootBeanDefinition(TheClassOfYourDynamicBean.class) // here you define the class
                 .setScope(BeanDefinition.SCOPE_SINGLETON)
                 .addDependsOn("someOtherBean") // make sure all other needed beans are initialized
    
                 // you can set factory method, constructor args using other methods of this builder
    
                 .getBeanDefinition();
    
            registry.registerBeanDefinition("your.bean.name", dynamicBean);           
    
    }
    
    @Component
    class SomeOtherClass {
    
        // NOTE: it is possible to autowire the bean
        @Autowired
        private TheClassOfYourDynamicBean myDynamicBean;
    
    }
    

    As presented above, you can still utilize Spring's Dependency Injection, because the post processor works on the actual Application Context.

提交回复
热议问题