如何在Spring中只销毁一个bean?

时间:2014-03-30 09:11:45

标签: java spring

我在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属性,但这不是我想要的。

提前致谢。

2 个答案:

答案 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个对象,而不会产生可能的布线问题。