Spring中Bean的五个作用域
当通过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的五种作用域 当通过spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域.Spring支持如下5种作用域: singleto ...
- Spring中bean的五个作用域简介(转载)
Spring上个版本的IoC容器支持两个不同的bean作用域(单例与原型).Spring 2.0改进了这一点,不仅提供了一些依赖于Spring部署环境(比如说,在web环境中的request和sess ...
- Spring入门(五):Spring中bean的作用域
1. Spring中bean的多种作用域 在默认情况下,Spring应用上下文中所有的bean都是以单例(singleton)的形式创建的,即不管给定的一个bean被注入到其他bean多少次,每次所注 ...
- 浅析Spring中bean的作用域
一.前言 刚刚花了点时间,阅读了一下Spring官方文档中,关于bean的作用域这一块的内容.Spring-4.3.21官方文档中,共介绍了七种bean作用域,这篇博客就来简单介绍一下这七种作用域 ...
- Spring中Bean的作用域、生命周期
Bean的作用域.生命周期 Bean的作用域 Spring 3中为Bean定义了5中作用域,分别为singleton(单例).protot ...
- spring中bean的作用域属性singleton与prototype的区别
1.singleton 当一个bean的作用域设置为singleton, 那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会 ...
- Spring02——Spring 中 Bean 的生命周期及其作用域
在前一篇文章中,我们已经介绍了 Spring IOC 的相关知识,今天将为个位介绍 Spring 中 Bean 的相关知识.关注我的公众号「Java面典」,每天 10:24 和你一起了解更多 Java ...
- 详解Spring中Bean的作用域与生命周期
摘要:在利用Spring进行IOC配置时,关于bean的配置和使用一直都是比较重要的一部分,同时如何合理的使用和创建bean对象,也是小伙伴们在学习和使用Spring时需要注意的部分,所以这一篇文章我 ...
- Spring中Bean的实例化
Spring中Bean的实例化 在介绍Bean的三种实例化的方式之前,我们首先需要介绍一下什么是Bean,以及Bean的配置方式. 如果 ...
随机推荐
- [转]Linux下is not in the sudoers file解决方法
来源: http://jingyan.baidu.com/article/2a1383284bb3e8074a134f2d.html 当我们使用sudo命令切换用户的时候可能会遇到提示以下错误:xxx ...
- Python学习(二) —— 运算符
一:Python的编码 python2的默认编码是ascii码,而python3的默认编码是utf-8 ASCII(American Standard Code for Information Int ...
- js 时间动画优化
function moveDivTimeBasedImprove(div, fps) { var left = 0; var current = +new Date; var previous = + ...
- CSS3 鲜为人知的属性-webkit-tap-highlight-color的理解
(一)-webkit-tap-highlight-color 这个属性只用于iOS (iPhone和iPad).当你点击一个链接或者通过Javascript定义的可点击元素的时候,它就 ...
- Codeforces 1071C Triple Flips 构造
原文链接 https://www.cnblogs.com/zhouzhendong/p/CF1071C.html 题目传送门 - CF1071C 题意 给定一个长度为 n 的 01 数列,限定你在 $ ...
- scrapy下载图片报[scrapy.downloadermiddlewares.robotstxt] DEBUG: Forbidden by robots.txt:错误
本文转自:http://blog.csdn.net/zzk1995/article/details/51628205 先说结论,关闭scrapy自带的ROBOTSTXT_OBEY功能,在setting ...
- mac 命令操作
内核空间和用户空间 x86架构中将内核地址空间划分三部分:ZONE_DMA.ZONE_NORMAL和 ZONE_HIGHMEM. 自动加载(开机自动启动服务) ln -sfv /usr/local/o ...
- JavaEE 之 log4j
1.log4j a.概念:一个非常优秀的开源日志记录工具 b.配置: ①src同目录下建立log4j.properties文件,书写: log4j.rootLogger=debug,appender1 ...
- C++学习之 —— 输入输出
案例:输入任意空格和数字,输出其中的数字之和. #include <iostream> using namespace std; int main() { ; cout << ...
- BZOJ-4-2038: [2009国家集训队]小Z的袜子(hose)-莫队
思路 :分块 思想 处理离线查询操作 对查询进行排序 在同一块内的按照 r 进行排序 不同块 的按照 L进行排序. #include<bits/stdc++.h> using names ...