Java 如何在 Spring 中只销毁一个 bean?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22742229/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to destroy only a single bean in Spring?
提问by JavaTechnical
I have a lot of singleton beans defined in my spring application context both different objects of the same type and objects of different types.
To do some pre-destroy operations, I have implemented the DisposableBean
interface for the bean classes. But, I would like to know how to destroy a bean with a particular id.
我在 spring 应用程序上下文中定义了很多单例 bean,包括相同类型的不同对象和不同类型的对象。为了做一些预销毁操作,我已经实现DisposableBean
了 bean 类的接口。但是,我想知道如何销毁具有特定 id 的 bean。
Here is my destroybean.xml
这是我的 destroybean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="st" class="spring17.Student">
<property name="sno" value="101"/>
<property name="sname" value="Smith"/>
<property name="age" value="20"/>
</bean>
<bean id="st1" class="spring17.Student">
<property name="sno" value="102"/>
<property name="sname" value="Scott"/>
<property name="age" value="22"/>
</bean>
</beans>
Here is my main class
这是我的主课
package spring17;
import org.springframework.context.support.GenericXmlApplicationContext;
public class SpringPrg {
@SuppressWarnings("resource")
public static void main(String args[])
{
GenericXmlApplicationContext gc=new GenericXmlApplicationContext("classpath:destroybean.xml");
Student st=gc.getBean("st",Student.class);
System.out.println(st);
gc.destroy();
}
}
When i call the gc.destroy()
st1
is also being destroyed which I don't want. You may suggest adding lazy-init
attribute for st1
but it is not what I wanted.
当我打电话时gc.destroy()
st1
,我不想要的也在被破坏。您可能会建议lazy-init
为其添加属性,st1
但这不是我想要的。
Thanks in advance.
提前致谢。
回答by Sotirios Delimanolis
As others have suggested, you need to get a reference to the BeanFactory
which the ApplicationContext
uses, cast it to a DefaultListableBeanFactory
and invoke the destroySingleton(..)
method
正如其他人所建议的,您需要获得BeanFactory
对ApplicationContext
使用的引用,将其转换为 aDefaultListableBeanFactory
并调用该destroySingleton(..)
方法
Student st = gc.getBean("st", Student.class);
((DefaultListableBeanFactory) gc.getBeanFactory()).destroySingleton("st");
The underlying DefaultListableBeanFactory
keeps a reference to your singleton beans. The call to destroySingleton(..)
will remove all references to the specified bean and call any DisposableBean
or other registered Spring-managed finalizers on it.
底层DefaultListableBeanFactory
保持对您的单例 bean 的引用。调用destroySingleton(..)
将删除对指定 bean 的所有引用,并在其上调用任何DisposableBean
或其他已注册的 Spring 管理的终结器。
However, your program has another reference to the instance in the variable st
. So you also need to clear that reference if you want the instance to be garbage collected.
但是,您的程序在变量 中有另一个对实例的引用st
。因此,如果您希望实例被垃圾回收,您还需要清除该引用。
st = null;
回答by Gray
But, I would like to know how to destroy a bean with a particular id.
但是,我想知道如何销毁具有特定 id 的 bean。
This seems to me to be an invalid question. The spring context is designed to be initialized and destroyed all at once. The idea that you would destroy just one of the wired beans that may be still in use by other beans seems to be dangerous indeed. There is no way that I know of, aside from some hackery, to get spring to forget about one of the beans wired into the collection.
在我看来,这是一个无效的问题。spring 上下文被设计为一次初始化和销毁。仅销毁一个可能仍被其他 bean 使用的有线 bean 的想法似乎确实很危险。据我所知,除了一些黑客之外,没有办法让春天忘记连接到集合中的一个豆子。
If you want beans to be dynamic then I would have some sort of StudentManager
bean instead. This manager would maintain its own collection of Student
objects. These students would not be wired via Spring but the manager would be. You could then create and destroy Student
objects at will without creating possible wiring problems.
如果您希望 bean 是动态的,那么我将使用某种StudentManager
bean。该管理器将维护自己的Student
对象集合。这些学生不会通过 Spring 连接,但经理会。然后您可以随意创建和销毁Student
对象,而不会造成可能的接线问题。