当前位置: 首页 > news >正文

为什么Spring中的bean默认都是单例模式?

省流小助手:主要是为了提升性能。希望知道原理的小伙伴继续往下看。

大家都知道Spring中的bean默认情况下都是单例模式(Singleton),那为什么呢?想要弄明白这个问题,首先需要对反射有一定的了解。

在Spring中,bean基本都是通过反射的方式创建的。反射可以动态的创建和使用对象,降低系统耦合,提高代码的复用率。因此反射十分适合于Spring这种注重自身拓展性的框架。但是,反射有一个致命的缺点,效率太低了

那么接下来,让我们通过一个简单的实验来看看反射和通过new创建对象的效率对比:

		long start = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            Core core = new Core();
        }
        long end = System.currentTimeMillis();
        System.out.println("new耗时:" + (end - start));

        start = System.currentTimeMillis();
        Class<Core> clazz = Core.class; //获取全限定类名
        Constructor<Core> declaredConstructor = clazz.getDeclaredConstructor(); //获取构造函数
        for (int i = 0; i < 1000000000; i++) {
            declaredConstructor.newInstance();
        }
        end = System.currentTimeMillis();
        System.out.println("反射耗时:" + (end - start));

上面分别统计了通过new和反射创建1000000000个Core(我自己定义的)对象消耗的时间,结果如下。由此可知,反射创建对象的效率是很低的。这也正是Spring为什么要用单例模式的原因,主要是为了减少对象创建来提升性能
在这里插入图片描述


Spring对象默认单例的优点

  • 通过减少对象创建的次数,降低反射的低效率对于框架整体性能的影响。
  • 对象创建的少,GC自然也就少了,提高性能。
  • 可以更快速的获取到bean。这个涉及到Spring的三级缓存,只有在第一次创建对象时才会去创建,其余的都是从第一级缓存直接获取,提高性能。

Spring对象默认单例的缺点

  • 会带来线程安全问题,有状态bean(能存储数据的bean)在单例模式下线程不安全。因此,Spring也提供了其他多种bean的作用域。

相关文章:

  • 【日常需求】一次使用EasyExcel而引发的问题与思考~
  • Docker 镜像拉取
  • Android 12 蓝牙打开
  • Linux常用基本命令详解(一)
  • 逻辑漏洞——业务逻辑问题
  • C++-vector的代码实现(超详细)
  • Linux之Platform设备驱动
  • Linux 入门篇
  • Linux驱动开发:字符设备驱动开发实战
  • 一、k8s的安装部署
  • VB.net:VB.net编程语言学习之ADO.net基本名称空间与类的简介、案例应用(实现与SQL数据库编程案例)之详细攻略
  • [iOS开发]事件处理与响应者链
  • 【CSDN线上竞赛第六期竞赛 】参赛介绍
  • 各种场景下的Git管理方法
  • 逻辑漏洞——权限控制问题
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • 《深入 React 技术栈》
  • 78. Subsets
  • Java多线程(4):使用线程池执行定时任务
  • Java小白进阶笔记(3)-初级面向对象
  • JAVA之继承和多态
  • jquery ajax学习笔记
  • magento 货币换算
  • MySQL的数据类型
  • Python十分钟制作属于你自己的个性logo
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • React 快速上手 - 07 前端路由 react-router
  • 关于字符编码你应该知道的事情
  • 理解在java “”i=i++;”所发生的事情
  • 如何进阶一名有竞争力的程序员?
  • 译自由幺半群
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • (003)SlickEdit Unity的补全
  • (C语言)输入一个序列,判断是否为奇偶交叉数
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (南京观海微电子)——I3C协议介绍
  • (一)SpringBoot3---尚硅谷总结
  • (转)EXC_BREAKPOINT僵尸错误
  • (转)Linux整合apache和tomcat构建Web服务器
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • .NET 事件模型教程(二)
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • .NET/C# 使用 #if 和 Conditional 特性来按条件编译代码的不同原理和适用场景
  • @DataRedisTest测试redis从未如此丝滑
  • [ASP.NET MVC]Ajax与CustomErrors的尴尬
  • [AutoSar NVM] 存储架构
  • [BZOJ4016][FJOI2014]最短路径树问题
  • [C++从入门到精通] 14.虚函数、纯虚函数和虚析构(virtual)