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());