Java 如何在SpringWebApplicationContext中在运行时添加bean实例?

Java 如何在SpringWebApplicationContext中在运行时添加bean实例?,java,spring,spring-mvc,Java,Spring,Spring Mvc,所以,标题很简单。我有一个处理程序类DynamicBeanHandler,它实现了spring提供的BeanDefinitionRegistryPostProcessor接口。在这个类中,我添加了多个SCOPE\u SINGLETONbean,它们的bean类设置为MyDynamicBean,如下所示- GenericBeanDefinition myBeanDefinition = new GenericBeanDefinition(); myBeanDefinition.setBeanCla

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

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);
    }
}
公共类SpringUtil实现ApplicationContextAware{
私有静态应用上下文应用上下文;
@凌驾
public void setApplicationContext(ApplicationContext ApplicationContext)抛出BeansException{
SpringUtil.applicationContext=applicationContext;
}
公共静态应用程序上下文getApplicationContext(){
返回applicationContext;
}
公共静态对象getBean(字符串beanId){
返回applicationContext.getBean(beanId);
}
公共静态T getBean(字符串beanId,类beanClass){
返回applicationContext.getBean(beanId,beanClass);
}
}

您可以使用
BeanDefinitionRegistry
(查找API)动态删除或注册bean

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


您可以执行以下操作,而不是自动连接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());

您可以通过以下方式以编程方式创建具有注入依赖项的bean:

使用指定的 自动连线策略。此接口中定义的所有常量都是 这里支持。执行bean的完全初始化,包括 所有适用的BeanPostProcessor

@Autowired
应用上下文上下文;
AutowireCapableBeanFactory=context.getAutowireCapableBeanFactory();
MyDynamicBean=(MyDynamicBean)factory.createBean(MyDynamicBean.class,AUTOWIRE\u构造函数,false);

为什么要这样做?您正在尝试延迟初始化吗?所以,我想这样做是因为
MyDynamicBean
包含一些属性,我希望在运行时通过编程从数据库中更新这些属性。请注意,我想在初始化上下文后更新bean实例,并添加一个新的bean实例。@Abhishek您能发布当前
SpringUtil
?@javaguy-更新的代码吗。请检查。因此,如果这种类型转换有效,我可以在任何一个我可以接触到
ApplicationContext
的类中进行。是这样吗?但是只在
SpringUtil
中保留
ApplicationContext
,因为在太多地方公开
ApplicationContext
不是一个好主意bean的名称是什么?
AutowireCapableBeanFactory factory = context.getAutowireCapableBeanFactory();
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) factory;
registry.removeBeanDefinition("myBean");
context.registerBean("myBean", MyBean.class, () -> new MyBean());