Spring - 我如何销毁我的原型范围的 bean?

发布于 2024-12-22 19:27:21 字数 1190 浏览 4 评论 0 原文

我有一个单例 bean,它有一个创建原型 bean 实例的方法。我正在使用方法 记录在此处以获取原型 bean 的实例。

public class SingletonService implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    public void go() {

        MyPrototypeBean prototype = applicationContext
            .getBean(MyPrototypeBean.class);

        prototype.doSomething();
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
        throws BeansException {

        this.applicationContext = applicationContext;
    }
}

起初我认为这已经足够好了,当“go”方法返回时,我的“prototype”实例将超出范围,这意味着该实例将没有引用并且将被垃圾收集。

然而,一位同行指出了以下声明 文档

客户端代码必须清理原型范围的对象并释放 原型 bean 所持有的昂贵资源。

听起来 Spring 会保留一个引用,所以 gc 永远不会拾取它?如果是这种情况,我该如何告诉 Spring 释放引用?文档提到我可以使用“自定义 bean 后处理器”,但不清楚该处理器适合在哪里以及它将运行什么代码。

预先感谢大家的帮助, 罗伊

I've got a singleton bean that has a method that creates instances of a prototype bean. I'm using the method documented here to get instances of the prototype bean.

public class SingletonService implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    public void go() {

        MyPrototypeBean prototype = applicationContext
            .getBean(MyPrototypeBean.class);

        prototype.doSomething();
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
        throws BeansException {

        this.applicationContext = applicationContext;
    }
}

At first I thought that this was good enough, that my instance of 'prototype' would go out of scope when the 'go' method returned, meaning that the instance would have not reference and would be garbage collected.

However, a peer pointed out the following statement from the documentation:

The client code must clean up prototype-scoped objects and release
expensive resources that the prototype bean(s) are holding.

So it sounds like Spring will retain a reference, and so the gc will never pick it up? If that's the case how do I tell Spring to release the reference? The documentation mentions that I can use a 'custom bean post-processor', but it's not clear where that processor would fit in and what code it would run.

Thanks all in advance for helping out,
Roy

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

皇甫轩 2024-12-29 19:27:21

我认为您误解了文档。只是说Spring不会管理原型bean的生命周期,因此@PreDestroy(等)方法需要由您自己的代码调用。 Spring不会保留引用。

I think you're misunderstanding the documentation. It's just saying Spring won't manage the lifecycle of the prototype bean, so @PreDestroy (etc.) methods need to be called by your own code. Spring won't retain a reference.

伏妖词 2024-12-29 19:27:21

只是为了让上面的 artbristol 答案更加清晰:artbristol 是正确的。 Spring 将创建您的代码所需的原型 bean,但不会销毁它。此行为是设计使然,因为它被认为更有效地允许垃圾收集器在原型依赖项超出范围时“拾取”原型依赖项。如果不这样做,那么唯一的其他选择是 Spring 容器在创建原型 bean 的每个实例时保留对它们的引用。鉴于您的代码每次调用时都会创建一个新的 MyPrototypeBean bean 实例,这意味着您可能会生成过多的 MyPrototypeBean 实例,这些实例会被收集但不会被销毁,因为销毁仅在 Spring 容器关闭时发生。您会发现这很容易导致快速内存泄漏。

因此,根据设计,原型 bean 由垃圾收集器处理,当它们超出范围或手动调用它们的销毁方法时被销毁。

文档所说的是,如果 MyPrototypeBean 占用任何资源(例如数据库连接),那么这将阻止该资源被正确释放。因此,编码员有责任对此进行管理。

Just to add some clarity to artbristol's answer above: artbristol is correct. Spring will create the prototype bean required by your code, but will not destroy it. This behaviour is by design as it is considered to be more effective to allow the garbage collector to 'pick up' your prototype dependency once it goes out of scope. If it was not done this way, then the only other alternative would be for Spring container to retain a reference to each and every instance of your prototype bean as they are created. Given that your code creates a NEW instance of MyPrototypeBean bean each time it is called, this means you could potentially have too many instances of MyPrototypeBean being generated, collecting but not being destroyed because destruction only occurs with the closing of the Spring Container. You can appreciate that this could very easily lead to a rapid memory leak.

As a result, it is by design that prototype beans are handled by the garbage collector, being destroyed as and when they go out of scope OR when their destruction methods are manually called.

What the documentation is saying is that IF MyPrototypeBean is holding onto any resources such as a database connection, then this will prevent that resource being properly released. It therefore becomes the coder's responsibility to manage this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文