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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 17:37:32  来源:igfitidea点击:

How to destroy only a single bean in Spring?

javaspring

提问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 DisposableBeaninterface 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()st1is also being destroyed which I don't want. You may suggest adding lazy-initattribute for st1but 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 BeanFactorywhich the ApplicationContextuses, cast it to a DefaultListableBeanFactoryand invoke the destroySingleton(..)method

正如其他人所建议的,您需要获得BeanFactoryApplicationContext使用的引用,将其转换为 aDefaultListableBeanFactory并调用该destroySingleton(..)方法

Student st = gc.getBean("st", Student.class);
((DefaultListableBeanFactory) gc.getBeanFactory()).destroySingleton("st");

The underlying DefaultListableBeanFactorykeeps a reference to your singleton beans. The call to destroySingleton(..)will remove all references to the specified bean and call any DisposableBeanor 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 StudentManagerbean instead. This manager would maintain its own collection of Studentobjects. These students would not be wired via Spring but the manager would be. You could then create and destroy Studentobjects at will without creating possible wiring problems.

如果您希望 bean 是动态的,那么我将使用某种StudentManagerbean。该管理器将维护自己的Student对象集合。这些学生不会通过 Spring 连接,但经理会。然后您可以随意创建和销毁Student对象,而不会造成可能的接线问题。