自定义 Bean 作用域需实现 Scope 接口并注册到容器,如线程级作用域通过 ThreadLocal 管理实例,注册时指定作用域名(如 "thread"),再用 @Scope("thread") 声明使用,注意内存泄漏与销毁回调手动触发。

Spring Boot 中自定义 Bean 的作用域,核心是实现 Scope 接口,并将其注册到 Spring 容器中。它不是简单加个注解就能生效,而是需要手动注入自定义作用域的实例,并声明哪些 Bean 使用它。
实现 Scope 接口
你需要创建一个类,实现 org.springframework.beans.factory.config.Scope 接口。比如线程级作用域常见写法:
- 重写
get()方法:从当前线程上下文(如ThreadLocal<map></map>)获取或创建 Bean 实例 - 重写
remove()方法:从线程上下文中移除指定 Bean - 重写
registerDestructionCallback():可选,用于在作用域结束时触发清理逻辑 - 重写
resolveContextualObject()和getConversationId():按需返回上下文标识(如线程 ID)
注册自定义作用域
仅实现接口还不够,必须让 Spring 容器“认识”这个作用域。通常在配置类中完成:
- 定义一个
@Bean方法,返回你实现的Scope实例(例如new CustomThreadScope()) - 通过
ConfigurableBeanFactory.registerScope()注册,一般在@PostConstruct或ApplicationContextInitializer中执行 - 注册时需指定唯一作用域名,如
"thread",后续就用这个名字引用
在 Bean 上使用自定义作用域
注册成功后,就可以在任意 @Bean 或 @Component 类上使用:
- 用
@Scope("thread")(字符串值必须与注册时一致) - 如果该 Bean 是 Web 环境下使用的,且可能被代理(如注入到 singleton Bean 中),建议加上
proxyMode = ScopedProxyMode.TARGET_CLASS - 注意:自定义作用域不支持通过 XML 配置,只适用于 Java 配置方式
注意事项
自定义作用域属于高级用法,实际项目中较少手写,除非有明确需求(如多租户隔离、事务线程绑定、异步任务上下文等):
- 务必确保
get()中的线程上下文初始化和清理正确,避免内存泄漏 - Spring 不会自动管理自定义作用域中 Bean 的销毁,
registerDestructionCallback()返回的Runnable需由你主动触发 - 测试时注意线程复用问题(如 Tomcat 线程池、@Async 线程),建议配合日志或断点验证实例是否真正隔离


















