spring中bean的五个作用域

     2022-03-27     475

关键词:

当通过spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域。Spring支持如下5种作用域:

  • singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例

  • prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例

  • request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效

  • session:对于每次HTTP Session,使用session定义的Bean豆浆产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效

  • globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效

  其中比较常用的是singleton和prototype两种作用域。对于singleton作用域的Bean,每次请求该Bean都将获得相同的实例。容器负责跟踪Bean实例的状态,负责维护Bean实例的生命周期行为;如果一个Bean被设置成prototype作用域,程序每次请求该id的Bean,Spring都会新建一个Bean实例,然后返回给程序。在这种情况下,Spring容器仅仅使用new 关键字创建Bean实例,一旦创建成功,容器不在跟踪实例,也不会维护Bean实例的状态。

  如果不指定Bean的作用域,Spring默认使用singleton作用域。Java在创建Java实例时,需要进行内存申请;销毁实例时,需要完成垃圾回收,这些工作都会导致系统开销的增加。因此,prototype作用域Bean的创建、销毁代价比较大。而singleton作用域的Bean实例一旦创建成功,可以重复使用。因此,除非必要,否则尽量避免将Bean被设置成prototype作用域。

 

曾经面试的时候有面试官问我spring的controller是单例还是多例,结果
我傻逼的回答当然是多例,要不然controller类中的非静态变量如何保证是线程安全的,这样想起似乎是对的,但是不知道(主要是我没看过
spring的源码,不知道真正的内在意图)为什么spring的controller是单例的。

先看看spring的bean作用域有几种,分别有啥不同。

spring bean作用域有以下5个:

singleton:单例模式,当spring创建applicationContext容器的时候,spring会欲初始化所有的该作用域实例,加上lazy-init就可以避免预处理;

prototype:原型模式,每次通过getBean获取该bean就会新产生一个实例,创建后spring将不再对其管理;

====下面是在web项目下才用到的===

request:搞web的大家都应该明白request的域了吧,就是每次请求都新产生一个实例,和prototype不同就是创建后,接下来的管理,spring依然在监听

session:每次会话,同上

global session:全局的web域,类似于servlet中的application

好了,上面都说了spring的controller默认是单例,那很自然就是singleton了。

再看一个例子,看看单例会不会有我说的那种问题(就是类中定义的非静态变量线程安全问题),当然下面这个例子我是实验过的, 要不然也不敢发出来

为什么spring要默认是单例呢?原因有二:

1、为了性能。

2、不需要多例。

1、这个不用废话了,单例不用每次都new,当然快了。

2、不需要实例会让很多人迷惑,因为spring mvc官方也没明确说不可以多例。

我这里说不需要的原因是看开发者怎么用了,如果你给controller中定义很多的属性,那么单例肯定会出现竞争访问了。

因此,只要controller中不定义属性,那么单例完全是安全的。下面给个例子说明下:


默认单例的

1|2

package
com.lavasoft.demo.web.controller.lsh.ch5;

import
org.springframework.context.annotation.Scope;

import
org.springframework.stereotype.Controller;

import
org.springframework.ui.ModelMap;

import
org.springframework.web.bind.annotation.RequestMapping;

/**

* Created by Administrator on 14-4-9.

*

* @author leizhimin 14-4-9 上午10:55

*/

@Controller

@RequestMapping("/demo/lsh/ch5")

public
class MultViewController {

privateintindex =
0; //非静态

@RequestMapping("/show")

publicStringtoShow(ModelMap model) {

System.out.println(++i);

return"/lsh/ch5/show";

}

@RequestMapping("/test")

publicStringtest() {

System.out.println(++i);

return"/lsh/ch5/test";

}

}

改为多例的(就是在class上面加一个@Scope("request")):

1 | 1

从此可见,单例是不安全的,会导致属性重复使用。

最佳实践:

1、不要在controller中定义成员变量。

2、万一必须要定义一个非静态成员变量时候,则通过注解@Scope("prototype"),将其设置为多例模式。














































































































spring中bean的五种作用域?spring中的bean是线程安全的吗?

spring中bean的五种作用域当通过spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域。Spring支持如下5种作用域:singleton:单例模式,在整个SpringIoC容器中,使用singleton定义的Bean将只有一个... 查看详情

springbean作用域

Bean的作用域当在Spring中定义一个bean时,你必须声明该bean的作用域的选项。例如,为了强制Spring在每次需要时都产生一个新的bean实例,你应该声明bean的作用域的属性为prototype。同理,如果你想让Spring在每次需要时都返回同一个b... 查看详情

spring中bean的作用域

Spring中bean的作用域可以在xml配置文件(一般叫bean.xml或ApplicationContext.xml)中通过scope属性进行指定。 在Spring中,bean对象可以有多种作用域   singletion默认的,每个IOC容器只创建一个Bean实例   prototype每次... 查看详情

spring——bean的作用域

Spring中Bean的作用域有五种,分别是singleton、prototype、request、session、globalSession。其中request、session、globalSession这三个作用域只有在web开发中才会使用到。当在Spring中定义一个bean时,你必须声明该bean的作用域的选项,若没有声明... 查看详情

spring中bean的作用域属性

 当一个bean的作用域设置为singleton,那么springIOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。换言之,当把一个bean定义设置为singleton作用域时,SpringIOC容器... 查看详情

spring实战-bean作用域

Spring定义了多种域单例(Singleton):在整个应用中,只有一个实例原型(Prototype):每次注入或者通过Spring应用上线文获取时,都创建一个bean实例会话(Session):在web应用中,为每个会话创建一个bean.使用场景:购物车请求(Re... 查看详情

spring中bean的作用域(代码片段)

1:和变量一样,bean也有作用域,spring中我们可以为bean指定作用域:<bean id="" class=""  scope="....">2:作用域的种类singleton:单例模式,在spring中只有一个实例 查看详情

spring07----bean的作用域

...对象程序设计中一般指对象或变量之间的可见范围。而在Spring容器中是指其创建的Bean对象相对于其他Bean对象的请求可见范围。Spring提供“singleton”和“prototype”两种基本作用域,另外提供“request”、“session”、“globalsession”... 查看详情

聊聊spring中bean的作用域(代码片段)

前言今天分享一下springbean的作用域,理解bean的作用域能够在使用过程中避免一些问题,bean的作用域也是springbean创建过程中一个重要的点。Springbean的作用域类型singleton(单例模式):在整个应用程序的生命周期中,只创建一个B... 查看详情

spring中bean的作用域

   在Spring中,那些组成应用程序的主体及由SpringIoC容器所管理的对象,被称之为bean。简单地讲,bean就是由IoC容器初始化、装配及管理的对象,除此之外,bean就与应用程序中的其他对象没有什么区别了。而bean的定义... 查看详情

spring之bean的作用域与生命周期

在前面博客中提到容器启动获得BeanDefinition对象中有一个scope属性。该属性控制着bean对象的作用域。本章节介绍Bean的作用域及生命周期,了解bean是怎么来的又怎么没的。一、Bean的作用域在Bean容器启动会读取bean的xml配置文件,... 查看详情

spring核心技术——spring中bean的作用域

前文概述了Spring的容器,Bean,以及依赖的一些信息,本文将描述一下Bean的作用域Bean的作用域当开发者定义Bean的时候,同时也会定义了该如何创建Bean实例。这些具体创建的过程是很重要的,因为只有通过对这... 查看详情

spring之bean的作用域

...tingthespiritofopensource,Spreadingtechnologyknowledge;)二bean的作用域spring定义了多种bean的作用域,常用的4种如下:单例(Singleton):在整个应用中,只创建bean的一个实例。原型(Prototype):每次注入或者通过Spring应用上下文获 查看详情

spring框架学习----bean作用域(代码片段)

文章目录Spring框架学习(六)----Bean作用域一、singleton(单例模式)二、protoType(原型模式)Spring框架学习(六)----Bean作用域  经过前面的学习,我们可以知道bean是存在作用域的。  从spring的官方文档中发现sp... 查看详情

在spring中,bean有几种作用域?

...1、singleton作用域当一个bean的作用域设置为singleton,那么SpringIOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。换言之,当把一个bean定义设置为singleton作用域时... 查看详情

spring配置文件中能够用到的bean的作用域有哪些

...ingleton作用域:当把一个bean定义设置为singleton作用域是,springioc容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回该bean的同一实例。值得强调的是singleton作用域是spring中的缺省作... 查看详情

8--深入使用spring--2...2指定bean的作用域

      8.2.2指定Bean的作用域        当使用XML配置方式来配置Bean实例时,可以通过scope来指定Bean实例的作用域,没有指定scope属性的Bean实例作用域默认是singleton。        当采用零配置方式来管理Bean实... 查看详情

关于 Spring bean 容器中的作用域和垃圾回收

】关于Springbean容器中的作用域和垃圾回收【英文标题】:RegardingthescopeandgarbagecollectioninSpringbeancontainer【发布时间】:2011-12-0716:45:29【问题描述】:我是Spring新手,目前正在我的一个项目中使用它。我了解到Spring容器包含所有bean... 查看详情