java 如何在 Spring WebApplicationContext 中在运行时添加 bean 实例?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43051394/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 07:02:26  来源:igfitidea点击:

How to add bean instance at runtime in spring WebApplicationContext?

javaspringspring-mvc

提问by Abhishek

So, the title is pretty straightforward. I have a handler class DynamicBeanHandlerwhich implements BeanDefinitionRegistryPostProcessorinterface provided by spring. In this class I'm adding multiple SCOPE_SINGLETONbeans which have bean class set as MyDynamicBeanas follows-

所以,标题很简单。我有一个处理程序类DynamicBeanHandler,它实现BeanDefinitionRegistryPostProcessor了 spring 提供的接口。在这个类中,我添加了多个SCOPE_SINGLETONbean,它们的 bean 类设置MyDynamicBean如下-

GenericBeanDefinition myBeanDefinition = new GenericBeanDefinition();
myBeanDefinition.setBeanClass(MyDynamicBean.class);
myBeanDefinition.setScope(SCOPE_SINGLETON);
myBeanDefinition.setPropertyValues(getMutableProperties(dynamicPropertyPrefix));
registry.registerBeanDefinition(dynamicBeanId, myBeanDefinition);

The method getMutableProperties()returns an object of MutablePropertyValues.

该方法getMutableProperties()返回一个对象MutablePropertyValues

Later on, I do SpringUtil.getBean(dynamicBeanId)to fetch the required MyDynamicBeaninstance where SpringUtilclass implements ApplicationContextAware. All this works great. The problem comes when I want to remove one of these instances and add a new instance later on where I don't have the registry instance. Can anyone please help me find a way to do this?

后来,我这样做SpringUtil.getBean(dynamicBeanId),以获取所需的MyDynamicBean其中instanceSpringUtil类实现ApplicationContextAware。所有这些都很好用。当我想删除这些实例之一并稍后在我没有注册表实例的地方添加一个新实例时,问题就出现了。谁能帮我找到一种方法来做到这一点?

Following is the code for class SpringUtil-

以下是类的代码SpringUtil-

public class SpringUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringUtil.applicationContext = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static Object getBean(String beanId) {
        return applicationContext.getBean(beanId);
    }

    public static <T> T getBean(String beanId, Class<T> beanClass) {
        return applicationContext.getBean(beanId, beanClass);
    }
}

回答by developer

You can make use of BeanDefinitionRegistry(look herefor API) to remove or register the beans dynamically.

您可以使用BeanDefinitionRegistry在此处查找 API)来动态删除或注册 bean。

So, in your SpringUtilclass, you can add the below method to remove the existing bean definition using removeBeanDefinition()and then add a new bean definition by using registerBeanDefinition().

因此,在您的SpringUtil类中,您可以添加以下方法来删除现有的 bean 定义removeBeanDefinition(),然后使用添加新的 bean 定义registerBeanDefinition()

public void removeExistingAndAddNewBean(String beanId) {

   AutowireCapableBeanFactory factory = 
                   applicationContext.getAutowireCapableBeanFactory();
   BeanDefinitionRegistry registry = (BeanDefinitionRegistry) factory;
   registry.removeBeanDefinition(beanId);

    //create newBeanObj through GenericBeanDefinition

    registry.registerBeanDefinition(beanId, newBeanObj);
}