我在Spring应用程序上下文中定义了很多单例bean,它们是相同类型的不同对象和不同类型的对象。
为了做一些预破坏操作,我已经为bean类实现了DisposableBean
接口。但是,我想知道如何销毁具有特定id的bean。
这是我的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>
这是我的主要课程
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();
}
}
当我打电话时,gc.destroy()
st1
也被摧毁,我不想要。您可以建议为lazy-init
添加st1
属性,但这不是我想要的。
提前致谢。
答案 0 :(得分:1)
正如其他人所建议的那样,您需要引用BeanFactory
使用的ApplicationContext
,将其投放到DefaultListableBeanFactory
并调用destroySingleton(..)
方法
Student st = gc.getBean("st", Student.class);
((DefaultListableBeanFactory) gc.getBeanFactory()).destroySingleton("st");
底层DefaultListableBeanFactory
保留对您的单例bean的引用。对destroySingleton(..)
的调用将删除对指定bean的所有引用,并调用任何DisposableBean
或其他已注册的Spring管理的终结器。
但是,您的程序对变量st
中的实例有另一个引用。因此,如果您希望对实例进行垃圾回收,则还需要清除该引用。
st = null;
答案 1 :(得分:1)
但是,我想知道如何销毁具有特定id的bean。
在我看来这是一个无效的问题。弹簧上下文旨在一次性初始化和销毁。您只会破坏其他bean可能仍在使用的其中一个有线bean的想法似乎确实很危险。除了一些hackery之外,我不知道如何让春天忘记连接到集合中的一个bean。
如果你想要bean是动态的,那么我会改为使用某种StudentManager
bean。该经理将维护自己的Student
个对象集合。这些学生不会通过Spring连接,但经理会。然后,您可以随意创建和销毁Student
个对象,而不会产生可能的布线问题。