如何销毁现有 bean 并替换为新定义 Spring - 在运行时

How to destroy existing bean and replace with new definition Spring - during Runtime

我有一个场景,我有一个网络应用程序。在我的网络应用程序中,我从另外 2 个 jar 文件导入了 "applicationContext.xml"。导入的两个context文件中,公共bean很少。 在我的一个 class 网络应用程序中,我遇到了一种情况,我正在使用两个罐子中的函数。

Function 1 from jar 1 : getEmployeeDetails() - needs "employeeBean" - "com.practice.Employee"

Function 2 from jar 2 : getEmployeeSalaryBreakup() - needs "employeeBean" - "com.practice.compensation.Employee"

现在的问题是,第二个函数调用中断了,因为它无法映射 bean。它给出 classCastException。 我没有在我的网络应用程序中自动装配 beans,它们是在 jar 文件中调用的。

我尝试过的解决方案之一是销毁现有的 bean 并重新初始化。相同的 PSB 代码:

/*
getEmployeeDetails()  //call here, uses employeeBean - com.practice.Employee
*/

ConfigurableApplicationContext configContext = (ConfigurableApplicationContext)applicationContext;

SingletonBeanRegistry registry = configContext.getBeanFactory();

registry.destroyBean("employeeBean"); //trying to destroy existing bean

registry.registerSingleton("employeeBean", "com.practice.compensation.Employee"); //reinitialize bean with new definition

/*
getEmployeeSalaryBreakup() //call here, expecting it will use new bean definition
*/

上面的实现对我不起作用, "registry.destroyBean("employeeBean");" - 即使在执行此行之后,旧的 bean 定义仍然存在。

有人可以建议我缺少什么,或者其他一些解决方案来完成这个。由于 jar 文件及其上下文文件不在我的控制范围内。所以我需要在网络应用级别处理这个问题。

您可以尝试在 applicationContext 上调用 refresh(),在 destroying/registering 您的 bean 之后:

configContext.refresh()

最后是这样的:

/*
call function getEmployeeDetails() //uses "employeeBean" - "com.practice.Employee"
*/

BeanDefinitionRegistry beanRegistry = (BeanDefinitionRegistry) applicationContext.getAutowireCapableBeanFactory();
BeanDefinition newBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(com.practice.compensation.Employee.class).getBeanDefinition();
BeanDefinition oldBeanDefinition = beanRegistry.getBeanDefinition("employeeBean");//this is needed if u want to revert your bean changes back to how it was
beanRegistry.registerBeanDefinition("employeeBean", newBeanDefinition);

/*
call function getEmployeeSalaryBreakup() //this will now execute as it gets required bean "employeeBean" - "com.practice.compensation.Employee"
*/

//reverting back bean changes
beanRegistry.registerBeanDefinition("employeeBean", oldBeanDefinition);