如何在春季WebApplicationContext中运行时添加Bean实例?

2022-09-02 09:55:32

所以,标题非常简单。我有一个处理程序类,它实现了spring提供的接口。在本类中,我添加了多个bean,其bean类设置如下 -DynamicBeanHandlerBeanDefinitionRegistryPostProcessorSCOPE_SINGLETONMyDynamicBean

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)MyDynamicBeanSpringUtilApplicationContextAware

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

答案 1

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

因此,在您的类中,您可以添加以下方法来删除现有的 Bean 定义,然后使用 添加新的 Bean 定义。SpringUtilremoveBeanDefinition()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);
}

答案 2

而不是自动布线 WebApplicationContext 你可以做

@Autowired
private GenericWebApplicationContext context;

然后,您可以注册新bean或删除旧bean并注册新bean

AutowireCapableBeanFactory factory = context.getAutowireCapableBeanFactory();
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) factory;
registry.removeBeanDefinition("myBean");
context.registerBean("myBean", MyBean.class, () -> new MyBean());

推荐