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


问题内容

因此,标题非常简单。我有一个处理程序类DynamicBeanHandler,它实现BeanDefinitionRegistryPostProcessor了spring提供的接口。在这个类中,我要添加多个SCOPE_SINGLETON具有MyDynamicBean如下bean类设置的bean

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

该方法getMutableProperties()返回的对象MutablePropertyValues

稍后,我SpringUtil.getBean(dynamicBeanId)将获取类实现的必需MyDynamicBean实例。所有这些都很好。当我要删除其中一个实例并在以后没有注册表实例的位置添加新实例时,就会出现问题。谁能帮我找到一种方法吗?SpringUtil``ApplicationContextAware

以下是该类的代码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);
    }
}

问题答案:

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

因此,在您的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);
}