Spring spring

Spring中文网站 > Spring Boot > Spring多例要怎么设置 Spring多例对象会自动销毁吗
Spring多例要怎么设置 Spring多例对象会自动销毁吗
发布时间:2026/08/20 11:37:47

品牌型号:联想ThinkPad X1

系统:Windows10家庭版

软件版本:Spring 5.3.7

用过Spring的小伙伴都知道Bean默认是单例的,至于多例Bean,真正用过且踩过坑的人并不多,毕竟我们项目中大部分业务场景用默认的单例Bean就够了,多例反而很少主动去碰。不过在有些场景下,多例是绕不开的。比如某个Bean持有状态、每次使用都需要一个全新的实例,这时候单例就不合适了。问题随之而来,多例怎么配置?用完之后Spring会不会帮我们销毁?下面就给大家介绍一下Spring多例要怎么设置,Spring多例对象会自动销毁吗的相关内容。

一、Spring多例要怎么设置

Spring默认给所有Bean用的是单例作用域,要改成多例,方式其实很简单,一个注解就可以搞定。我们在需要多例的类上加@Scope("prototype"),Spring就知道这个Bean不走单例那套逻辑了。每次从容器里获取这个Bean,都会重新创建一个新实例。写法如下:

使用@Scope注解
图1:使用@Scope注解

光加注解还不够,有一个细节很容易被大家忽略,如果我们在一个单例Bean里直接@Autowired注入了一个多例Bean,这个多例其实只会被创建一次,因为单例Bean只初始化一次,注入动作也只发生一次,后续拿到的始终是同一个实例,多例的效果就失效了。

错误注入方式
图2:错误注入方式

要解决这个问题,有几种常见的处理方式,我们可以让单例Bean实现ApplicationContextAware接口,持有ApplicationContext的引用,每次需要多例Bean的时候手动调getBean()去取,这样每次都能拿到新实例。也可以用Spring提供的@Lookup注解,标在一个方法上,Spring会在运行时覆盖这个方法的实现,每次调用都返回一个新的多例实例,代码侵入性比第一种小一些。还有一种方式是直接注入ObjectProvider,需要的时候调getObject()获取实例,写法更现代,Spring 4.3之后推荐这种方式。

注入ObjectProvider
图3:注入ObjectProvider

选哪种方式看实际情况,场景简单、调用频率不高,那就用ApplicationContext手动取就行,如果要追求代码整洁,@Lookup或者ObjectProvider都是可以的。

二、Spring多例对象会自动销毁吗

Spring是不会去管多例Bean销毁情况的,这一点和单例Bean有很大的区别,单例Bean的生命周期全都由Spring容器掌控,容器关闭的时候会自动调用Bean的销毁方法,比如@PreDestroy标注的方法或者destroy-method配置的方法。但多例Bean不一样,Spring只负责把它创建出来、初始化好、交给我们,后续怎么用、什么时候销毁,框架不再过问。

为什么Spring不管多例Bean的销毁?那是因为单例Bean全局就一个,容器拿着它的引用,关闭的时候统一处理很方便。但多例Bean每次都新建,容器里可能同时存在几十上百个实例,Spring如果要追踪每一个的生命周期,内存开销会很大,所以Spring干脆把这个责任交还给我们来管。

使用代码验证Spring是否销毁多例对象
图4:使用代码验证Spring是否销毁多例对象

这就意味着如果我们的多例Bean里有需要释放的资源,比如数据库连接、文件句柄、网络连接这类,就得我们自己在合适的时机手动调用销毁逻辑。靠@PreDestroy是不行的,Spring根本不会触发多例Bean的这个方法。给大家推荐一个稳妥的做法,让调用方在用完之后主动调释放方法,或者结合try-finally确保资源一定被清理掉。

结合try-finally确保资源被清理
图5:结合try-finally确保资源被清理

还有一种思路是借助Spring的DisposableBean接口,实现destroy()方法写好销毁逻辑,但前提是调用方记得手动调用,Spring不会自动触发。

手动销毁
图6:手动销毁

所以在决定用多例之前,先想清楚这个Bean有没有需要释放的资源。如果有,管理成本不低,得在代码设计上做好规划,别到最后搞出资源泄漏还找不到原因。

以上就是Spring多例要怎么设置,Spring多例对象会自动销毁吗的全部内容了。多例的设置不复杂,@Scope("prototype")加上去就行,但是要注意单例Bean注入多例失效的问题,根据场景选@Lookup或者ObjectProvider来解决。销毁这块是很多人容易忽略的地方,多例Bean Spring不会自动销毁,创建出来之后生命周期就交给我们自己管理了,Bean里如果有需要释放的资源,必须手动处理,不能指望框架兜底。

180 1563 6924