专项攻克-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不负责销毁。
相关推荐
小蒜学长6 分钟前
基于SpringBoot的佳新超市管理系统设计与实现系统(代码+数据库+LW)
java·数据库·spring boot·后端·佳新超市管理系统
sunshine22 girl30 分钟前
Java学习六 Java常见API-1-Radom随机数
java·开发语言·学习
IT_陈寒1 小时前
Vite静态资源导入这个坑我帮你们踩过了
前端·人工智能·后端
wangbing11251 小时前
使用jps jstack排查系统问题
java
于指尖飞舞1 小时前
java面试题总结
java·开发语言
打工仔折腾 AI1 小时前
把AI Agent托管在家用电脑:UU远程终端与端口映射实测记录
人工智能·后端·python·langchain·ai agent 实战
ZealSinger2 小时前
LangChain4j用AiServices拼Tool
java·rag·ai智能体·langchain4j
vx_Biye_Design2 小时前
springboot高校选课系统82776-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·课程设计·express
Sweet锦3 小时前
不调 Python,不装向量库:我用纯 Java 写了一套以图搜图引擎
java·人工智能·开源·图搜索