Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Spring 中的 bean 为什么默认单例?

Spring 中的 bean 为什么默认单例?

作者头像
Java技术栈
发布于 2020-02-12 06:27:55
发布于 2020-02-12 06:27:55
8420
举报
文章被收录于专栏:Java技术栈Java技术栈

熟悉Spring开发的朋友都知道Spring提供了5种scope分别是singleton、prototype、request、session、global session。

如下图是官方文档上的截图,感兴趣的朋友可以进去看看这五种分别有什么不同。

今天要介绍的是这五种中的前两种,也是Spring最初提供的bean scope singleton 和 prototype。

Spring官方文档介绍如下图:

更多内容可以看官方文档介绍,非常详细:

https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s04.html

单例bean与原型bean的区别

如果一个bean被声明为单例的时候,在处理多次请求的时候在Spring容器里只实例化出一个bean,后续的请求都公用这个对象,这个对象会保存在一个map里面。

当有请求来的时候会先从缓存(map)里查看有没有,有的话直接使用这个对象,没有的话才实例化一个新的对象,所以这是个单例的。

但是对于原型(prototype)bean来说当每次请求来的时候直接实例化新的bean,没有缓存以及从缓存查的过程。

1.画图分析

2.源码分析

生成bean时先判断单例的还是原型的

如果是单例的则先尝试从缓存里获取,没有在新创建

结论:

  1. 单例的bean只有第一次创建新的bean 后面都会复用该bean,所以不会频繁创建对象。
  2. 原型的bean每次都会新创建

单例bean的优势

由于不会每次都新创建新对象所以有一下几个性能上的优势:

1.减少了新生成实例的消耗

新生成实例消耗包括两方面,第一,Spring会通过反射或者cglib来生成bean实例这都是耗性能的操作,其次给对象分配内存也会涉及复杂算法。

2.减少jvm垃圾回收

由于不会给每个请求都新生成bean实例,所以自然回收的对象少了。

3.可以快速获取到bean

因为单例的获取bean操作除了第一次生成之外其余的都是从缓存里获取的所以很快。

单例bean的劣势

单例的bean一个很大的劣势就是他不能做到线程安全!!!

由于所有请求都共享一个bean实例,所以这个bean要是有状态的一个bean的话可能在并发场景下出现问题,而原型的bean则不会有这样问题(但也有例外,比如他被单例bean依赖),因为给每个请求都新创建实例。

总结

Spring 为啥把bean默认设计成单例?

答案:为了提高性能!!! 从几个方面:

  1. 少创建实例
  2. 垃圾回收
  3. 缓存快速获取

单例有啥劣势?

如果是有状态的话在并发环境下线程不安全。

作者:小小木

https://juejin.im/post/5cab7ebf518825177637b2f9

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java技术栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
面试题:Spring为什么默认bean为单例?
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
用户1212940
2019/11/03
1.4K0
一道78%的Java程序员搞不清的Spring bean面试题
熟悉Spring开发的朋友都知道Spring提供了5种scope分别是singleton、prototype、request、session、global session。
程序员追风
2019/08/08
3780
一道78%的Java程序员搞不清的Spring bean面试题
单例bean和原型bean的区别?
1.单例bean指的是在多次请求时spring都只会实例化一个对象,并存在map中并放入缓存中,如果后续有请求会先从缓存中查找bean,如果找不到在实例化一个bean 2.原型bean指的是每次请求都实例化一个bean,没有缓存查找 ![请输入图片描述][1]
用户9131103
2023/07/17
2780
Spring 单例 Bean 与多线程深度分析
Spring 的 bean默认是单例的,在高并发下,如果在 Spring 的单例 bean 中设置成员变量,则会发生并发问题。最近在进行开发时,错误的在单例的bean中使用了成员变量,导致多个线程大并发访问时,出现赋值错误及日志打印混乱的问题。
一个会写诗的程序员
2022/01/07
2.6K0
Spring 单例 Bean 与多线程深度分析
03 Spring框架 bean的属性以及bean前处理和bean后处理
整理了一下之前学习spring框架时候的一点笔记。如有错误欢迎指正,不喜勿喷。 上一节我们给出了三个小demo,具体的流程是这样的: 1.首先在aplicationContext.xml中添加<bean id="自定义id" class="包名.类名">。(还有两种工厂配置) 2.其次写一个自定义类,里面只包含一个系统输出的show()。 3.使用 ApplicationContext hw=new classpathXmlApplicationContext("applicationContext.xm
MindMrWang
2018/04/16
7600
Spring中Bean
一、什么是Bean 1、Java面向对象,对象有方法和属性,那么就需要对象实例来调用方法和属性(即实例化); 2、凡是有方法或属性的类都需要实例化,这样才能具象化去使用这些方法和属性; 3、规律:凡是子类及带有方法或属性的类都要加上注册Bean到Spring IoC的注解; 4、把Bean理解为类的代理或代言人(实际上确实是通过反射、代理来实现的),这样它就能代表类拥有该拥有的东西了。 5、我们都在微博上@过某某,对方会优先看到这条信息,并给你反馈,那么在Spring中,你标识一个@符号,那么Spring就
Zephery
2018/03/12
7410
Spring读源码系列04----bean的加载---上
spring 3.0版本,是将后置处理的代码放在了doGetObjectFromFactoryBean的return语句之前进行判断窒息的,但是现在最新版本放到了getObjectFromFactoryBean方法中
大忽悠爱学习
2022/05/10
4040
Spring读源码系列04----bean的加载---上
Spring IOC 容器源码分析 - 获取单例 bean
为了写 Spring IOC 容器源码分析系列的文章,我特地写了一篇 Spring IOC 容器的导读文章。在导读一文中,我介绍了 Spring 的一些特性以及阅读 Spring 源码的一些建议。在做完必要的准备工作后,从本文开始,正式开始进入源码分析的阶段。
田小波
2018/06/01
6660
Spring IOC 容器源码分析 - 获取单例 bean
Spring Ioc 之 Bean的加载(二)
Spring 只处理单例模式下得循环依赖,对于原型模式的循环依赖直接抛出异常。
周同学
2019/09/09
8830
Spring Ioc 之 Bean的加载(三):各个 scope 的 Bean 创建
createBean(beanName, mbd, args)方法比较复杂,在之后的文章中会详细分析,这里就先略过,直接看
周同学
2019/09/10
6530
Spring Ioc 之 Bean的加载(一)
当我们显示或者隐式地调用 BeanFactory#getBean(String name) 方法时,则会触发加载 Bean 阶段。代码如下:
周同学
2019/09/08
8080
Spring中Bean的细节
第二种方式:如果某个类在别人写的jar包中 无法通过修改源代码 使用默认构造函数时
暴躁的程序猿
2022/03/23
3180
Spring中Bean的细节
【死磕 Spring】----- IOC 之分析各 scope 的 bean 创建
在 Spring 中存在着不同的 scope,默认是 singleton ,还有 prototype、request 等等其他的 scope,他们的初始化步骤是怎样的呢?这个答案在这篇博客中给出。
用户1655470
2018/11/23
5470
面试必问:Spring循环依赖的三种方式
引言:循环依赖就是N个类中循环嵌套引用,如果在日常开发中我们用new 对象的方式发生这种循环依赖的话程序会在运行时一直循环调用,直至内存溢出报错。下面说一下Spring是如果解决循环依赖的。
用户5224393
2019/07/31
3590
面试必问:Spring循环依赖的三种方式
Spring系列之bean的使用
转载自 https://www.cnblogs.com/xiaoxi/p/5850095.html
allsmallpig
2021/02/25
6210
Spring系列第6篇:玩转bean scope,避免跳坑里!
应用中,有时候我们需要一个对象在整个应用中只有一个,有些对象希望每次使用的时候都重新创建一个,spring对我们这种需求也提供了支持,在spring中这个叫做bean的作用域,xml中定义bean的时候,可以通过scope属性指定bean的作用域,如:
路人甲Java
2020/02/18
7210
【死磕 Spring】----- IOC 之开启 bean 的加载
Spring IOC 容器所起的作用如上图所示,它会以某种方式加载 Configuration Metadata,将其解析注册到容器内部,然后回根据这些信息绑定整个系统的对象,最终组装成一个可用的基于轻量级容器的应用系统。
用户1655470
2018/11/06
6900
头条一面:Spring IOC容器中只存放单例Bean吗?
最近,很多小伙伴出去面试,感觉自己面的不是很理想,回来后,不少小伙伴把面试题做了记录发给我,让我给大家解析下,然后发出来。当我看到这些面试题时,快速在脑海中构建起了整个知识体系,从基础到框架、从分布式到微服务,从数据结构到算法,从虚拟化到云原生,从大数据到云计算,从实战项目到性能调优。其实,这些面试本质上不难,很多都是对于基础知识的考察。
冰河
2021/05/18
1.2K0
头条一面:Spring IOC容器中只存放单例Bean吗?
Spring读书笔记——bean创建(上)
通过《Spring读书笔记——bean加载》和《Spring读书笔记——bean解析》,我们明白了两件事。 Spring如何加载消化一个xml配置文件 Spring如何将xml文件的各种标签转换为BeanDefinition并注册到Spring容器下 现在,我们理所当然的还差bean是如何被创建出来这一环节了。 从getBean说起 我们经常使用下面的方式实现先加载xml文件,然后获取相应的bean实例 BeanFactory beanFactory = new ClassPathXmlApplicati
JackieZheng
2018/01/16
7200
Spring读书笔记——bean创建(上)
Spring - Bean 范围教程
定义 <bean> 时,您可以选择声明该 bean 的作用域。例如,要强制 Spring 在每次需要时生成一个新的 bean 实例,您应该将 bean 的 scope 属性声明为prototype。类似地,如果您希望 Spring 在每次需要时返回相同的 bean 实例,您应该将 bean 的 scope 属性声明为singleton。
IT胶囊
2021/08/20
6290
相关推荐
面试题:Spring为什么默认bean为单例?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文