专项攻克-SpringBoot启动后 Bean的实例数量问题

文章目录

SpringBoot Bean 实例数量面试题

核心答案

默认情况下:单例,整个Spring容器中这个Bean只有1个实例,但不是所有Bean都只有一个实例,由Scope作用域决定。

默认scope:@Scope("singleton") 单例。

5种Scope作用域

作用域 实例数量 说明
singleton(默认) 整个容器仅1个实例 Spring容器启动初始化(或懒加载),全局复用,绝大多数业务Bean
prototype 每次获取都新建一个对象 每次getBean()、@Autowired注入都创建新实例
request 每个HTTP请求1个实例 Web环境,一次请求一个bean
session 每个用户会话1个实例 Web环境,一个session一个bean
application Servlet上下文1个实例 整个web应用共享1个,和singleton类似

注意:request / session / application 只在web(SpringMVC)环境生效。

注解写法

复制代码
// 多例,每次拿都新建对象
@Scope("prototype")
@Component
public class DemoService {
}

⚠️高频坑点(面试必问)

坑1:单例Bean里面注入prototype多例Bean,不会产生新对象

复制代码
@Component // singleton单例
public class AService {
    @Autowired
    private BService bService; // BService上加了@Scope("prototype")
}

现象:AService是单例,容器创建AService的时候,只注入一次BService ,之后一直复用同一个BService,并不会每次调用都新建B。

原因:依赖注入只发生在A初始化那一次。

解决方案3种:

  1. 注入 ObjectProvider<BService>,每次getObject()获取新实例

    @Autowired
    private ObjectProvider bServiceProvider;

    // 使用的时候
    BService b = bServiceProvider.getObject();

  2. 注入ApplicationContext,手动getBean("bService")

  3. 使用代理模式 @Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)

坑2:单例Bean不要有成员变量(非线程安全)

singleton多线程共用同一个对象,如果Bean里面有成员变量存业务数据,并发会出现数据错乱!

✅正确:成员变量只用无状态对象(mapper、dao、配置);业务变量放方法局部变量。


面试问答

Q:Spring中Bean默认是单例,是单例模式的饿汉式还是懒汉式?

答:

  • 默认饿汉式:容器启动时就创建singleton bean;

  • 如果加 @Lazy 懒加载,变成懒汉式,第一次使用的时候才创建实例

    @Component
    @Lazy // 容器启动不创建,第一次获取才创建
    public class DemoService{}

Q:@Controller、@Service、@Repository、@Component 是什么scope?

全部默认 singleton 单例。

Q:prototype的Bean什么时候销毁?

singleton:容器关闭的时候Spring帮调用销毁方法;

prototype:Spring容器不管理销毁!容器不会帮你执行destroy回调,需要自己手动销毁。

Q:SpringBoot web项目中Controller是单例吗?会不会线程安全问题?

Controller默认singleton。

只要不要定义成员变量存请求数据就线程安全;请求参数全部放在方法参数,局部变量,多线程互不干扰。


三句背诵版(面试口述)

  1. Spring Bean默认scope是singleton,整个IOC容器只有一个实例;可以通过@Scope改成prototype多例,每次获取新建对象。
  2. 单例Bean注入多例Bean会出现"多例失效",因为依赖注入只发生一次,可以用ObjectProvider解决。
  3. singleton Bean要保证无状态,不能用成员变量存业务数据,避免并发线程安全问题;prototype BeanSpring不负责销毁。
相关推荐
凤山老林13 小时前
Spring Boot 整合 Flowable 的企业级落地指南
数据库·spring boot·后端·flowable·工作流
苏三说技术13 小时前
Kafka已正式接入AI
后端
企业数字化笔记13 小时前
AI写的系统出现504怎么办?接口超时和数据库慢查询排查
数据库·后端
IT_陈寒13 小时前
Redis的Set操作居然能把我的服务整挂了?
前端·人工智能·后端
momo0611713 小时前
Redis新手入门 -- 学习笔记
redis·后端
zhangjw3413 小时前
第47篇:Java综合实战:电商秒杀系统(高并发场景)
java·开发语言
井云AI14 小时前
vendor 资源包是什么:井云 DSH 客户端打包为什么离不开它
后端·智能体小程序
土司大王14 小时前
LeetCode hot100 回溯专题总结:Java 通用模板、决策树模型
java·算法·leetcode·决策树
重生之我是Java开发战士14 小时前
【Spring Cloud】Nacos注册中心
后端·spring·spring cloud
Wang's Blog14 小时前
Java框架快速入门:Spring Security+OAuth2之用户注册与唯一性校验实现
java·数据库·spring