Spring bean为什么默认是单例

熟悉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时先判断单例的还是原型的

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

结论:

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

二、单例bean的优势

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

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

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

2、减少jvm垃圾回收

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

3、可以快速获取到bean

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

三、单例bean的劣势

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

四、总结

1、Spring 为啥把bean默认设计成单例?为了提高性能少创建实例垃圾回收缓存快速获取

2、单例有啥劣势?

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

3、什么是有状态对象?什么是无状态对象?有状态对象:有实例变量可以标志其对象所处的状态。(有实例变量的对象,有存储数据能力)- 白话:有属性的对象无状态对象:无实例变量可以标志其对象所处的状态。(无实例变量的对象,无存储数据能力)- 白话:无属性的对象

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 简单了解Spring Bean常用注解的装配

    这篇文章主要介绍了简单了解Spring Bean常用注解的装配,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 基于注解的装配 在Spring框架中,尽管使用XML配置文件可以很简单地装配Bean,但如果应用中有大量的Bean需要装配,会导致XML配置文件过于庞大,不方便以后的升级与维护,因此更多的时候推荐开发者使用注解(annotation)的方式去装配Bean. 在Spring框架中定义了一系列的注解,下面介绍集中常用的注解. @Compon

  • spring ioc的简单实例及bean的作用域属性解析

    IoC(Inversion if Control)-控制反转是Spring俩大核心技术之一,IoC一般分为俩种类型:依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup) 使用示例: 1.新建工程并导入Spring相关jar包. 2.新建数据访问层及业务逻辑层 代码结构: 代码示例: /** * 实体Bean * @author BC * */ public class User { private Integer id; private

  • 简单了解Spring beanfactory循环依赖命名重复2大属性

    是否允许循环依赖和bean的命名重复取决于beanfactory的两大属性 allowBeanDefinitionOverriding和allowCircularReferences.这两个属性未指定时取的是DefaultListableBeanFactory中的默认值,均为true,即默认允许同名bean和循环引用(只有单例允许). 但是假如读者用的springboot版本比较新,就会发现情况并不是这样,同名bean会冲突报错.为什么呢,跟踪源码发现是Springboot应用在2.1.8版本的

  • 简单了解spring bean作用域属性singleton和prototype的区别

    这篇文章主要介绍了简单了解spring bean作用域属性singleton和prototype的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.singleton 当一个bean的作用域设置为singleton, 那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例. 换言之,当把一个bean定义设置为singleton作用域时,Sprin

  • SpringMVC中使用bean来接收form表单提交的参数时的注意点

    这是前辈们对于SpringMVC接收表单数据记录下来的总结经验: SpringMVC接收页面表单参数 springmvc请求参数获取的几种方法 下面是我自己在使用时发现的,前辈们没有记录的细节和注意点: 使用bean来接收form表单提交的参数时,pojo中必须含有默认的(即空的)构造函数,同时,需要设置到bean中的变量必须有setter方法. 注:以下代码均为示例代码,非本人实际运行代码,请自行补充. 例如:我有一个bean类是User,具有变量username和password.同时,表单

  • 简单了解spring bean的循环引用

    看过一次spring公开课,记录一下bean的循环引用问题. 问题: public class IndexService{ @Autowired IndexDao indexDao; } public class IndexDao{ @Autowired IndexService indexService; } 以上的实例中IndexService依赖IndexDao,IndexDao中依赖IndexService. spring在bean的实例化过程: 先去创建IndexDao bean, 1

  • 详解Spring简单容器中的Bean基本加载过程

    本篇将对定义在 XMl 文件中的 bean,从静态的的定义到变成可以使用的对象的过程,即 bean 的加载和获取的过程进行一个整体的了解,不去深究,点到为止,只求对 Spring IOC 的实现过程有一个整体的感知,具体实现细节留到后面用针对性的篇章进行讲解. 首先我们来引入一个 Spring 入门使用示例,假设我们现在定义了一个类 org.zhenchao.framework.MyBean ,我们希望利用 Spring 来管理类对象,这里我们利用 Spring 经典的 XMl 配置文件形式进行

  • 简单了解Spring中BeanFactory与FactoryBean的区别

    这篇文章主要介绍了简单了解Spring中BeanFactory与FactoryBean的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在Spring中有BeanFactory和FactoryBean这2个接口,从名字来看很相似,比较容易搞混. 一.BeanFactory BeanFactory是一个接口,它是Spring中工厂的顶层规范,是SpringIoc容器的核心接口,它定义了getBean().containsBean()等管理Be

  • 浅谈Spring单例Bean与单例模式的区别

    Spring单例Bean与单例模式的区别在于它们关联的环境不一样,单例模式是指在一个JVM进程中仅有一个实例,而Spring单例是指一个Spring Bean容器(ApplicationContext)中仅有一个实例. 首先看单例模式,在一个JVM进程中(理论上,一个运行的JAVA程序就必定有自己一个独立的JVM)仅有一个实例,于是无论在程序中的何处获取实例,始终都返回同一个对象,以Java内置的Runtime为例(现在枚举是单例模式的最佳实践),无论何时何处获取,下面的判断始终为真: // 基

  • Spring bean为什么默认是单例

    熟悉Spring开发的朋友都知道Spring提供了5种scope分别是singleton.prototype.request.session.global session. 如下图是官方文档上的截图,感兴趣的朋友可以进去看看这五种分别有什么不同.今天要介绍的是这五种中的前两种,也是Spring最初提供的bean scope singleton 和 prototype. Spring官方文档介绍如下图: 更多内容可以看官方文档介绍,非常详细: https://docs.spring.io/spri

  • 通过spring注解开发,简单测试单例和多例区别

    目录 通过spring注解开发,测试单例和多例区别 1.注解和配置两种用法形式 2.在spring框架中,scope作用域默认是单例的 3.实例 (1)多例: (2)单例(注解版) Spring中单例和多例的理解 1.什么是单例和多例 2.Spring中的单例与多例 单例bean与多例(原型)bean的区别: 3.单例的优势与劣势 优势: 劣势: 4.spring单例模式与线程安全: 如何解决线程安全问题? 5.单例如何变多例 通过spring注解开发,测试单例和多例区别 1.注解和配置两种用法

  • spring中向一个单例bean中注入非单例bean的方法详解

    目录 前言 错误实例演示 实现ApplicationContextAware接口 lookup method lookup method签名 总结 前言 看到这个题目相信很多小伙伴都是懵懵的,平时我们的做法大都是下面的操作 @Component public class People{ @Autowired private Man man; } 这里如果Man是单例的,这种写法是没有问题的,但如果Man是原型的,这样是否会存在问题. 错误实例演示 这里有一个原型(生命周期为prototype)的

  • Spring如何解决单例bean线程不安全的问题

    首先我们应该知道线程安全问题一般发生在成员变量上,这是为什么啦? 因为成员变量是存放在堆内存中,而堆内存又是线程共享的,这就造成了线程安全问题 因为Spring中的Bean默认是单例的,所以在定义成员变量时也有可能会发生线程安全问题.下面我们就来研究下如何解决Spring中单例Bean的线程安全问题 @RestController //@Scope("prototype") public class BeanController { private int content=0; //基

  • Spring中Bean的单例和多例使用说明

    目录 Bean的单例和多例使用 实战演示 Spring单例bean与原型bean区别和创建过程 singletonScope与prototypeScope Bean的单例和多例使用 在Spring中,bean可以被定义为两种模式:prototype(多例)和singleton(单例) singleton(单例):只有一个共享的实例存在,所有对这个bean的请求都会返回这个唯一的实例. prototype(多例):对这个bean的每次请求都会创建一个新的bean实例,类似于new. Spring

  • 浅谈Spring 的Controller 是单例or多例

    背景:今天写代码遇到一个Controller 中的线程安全问题,那么Spring 的Controller 是单例还是多例的呢?若为单例又如何保证并发安全呢? 一.面试回答 Spring管理的Controller,即加入@Controller 注入的类,默认是单例的,因此建议: 1.不要在Controller 中定义成员变量:(单例非线程安全,会导致属性重复使用) 2.若必须要在Controller 中定义一个非静态成员变量,则通过注解@Scope("prototype"),将其设置为多

  • Spring bean配置单例或多例模式方式

    目录 Spring bean配置单例或多例模式 单例 多例 Spring scope配置单例.多例模式 1.scope属性介绍 2.scope配置 3.单例模式底层实现模拟 Spring bean配置单例或多例模式 单例 spring bean 默认是单例默认,在对应.xml文件中的配置是: <bean id="user" class="..." scope="singleton"/> singleton就是配置这个bean是否是单例

  • Spring:bean注入--Set方法注入

    目录 Set 方法注入 总结 Set 方法注入 1.新建一个空的 maven项目. 2.导入依赖 properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!--这里是java 版本号--> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target

  • Spring Bean是如何初始化的详解

    目录 前言 三级缓存 doGetBean createBean doCreateBean instantiateBean instantiate instantiateClass 注入 AutowiredAnnotationBeanPostProcessor分析 postProcessProperties 如何实现bean注入的 总结 前言 做Java都有很多年了,一直有一个疑惑: Spring 如何初始化bean,怎么调用反射实例化对象的,自己动手来解除这个疑惑. 过去我认为spring be

随机推荐