springboot默认创建的bean是单实例
默认是单例
通过注解@Scope("prototype"),将其设置为多例模式
参考:
曾经⾯试的时候有⾯试官问我spring的controller是单例还是多例,结果我的回答当然是多例,要不然controller类中的⾮静态变量如何保证是线程安全的,这样想起似乎是对的,但是不知道(主要是我没看过spring的源码,不知道真正的内在意图)为什么spring的controller是单例的。springboot是啥
先看看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中不定义属性,那么单例完全是安全的。下⾯给个例⼦说明下:
@Controller
public class MultViewController {
private int index = 0;//⾮静态
@RequestMapping("/show")
public String toShow(ModelMap model) {
System.out.println(++i);
return"show";
}
@RequestMapping("/test")
public String test() {
System.out.println(++i);
return"test";
}
}
从此可见,单例是不安全的,会导致属性重复使⽤。
最佳实践:
1、不要在controller中定义成员变量。
2、万⼀必须要定义⼀个⾮静态成员变量时候,则通过注解@Scope("prototype"),将其设置为多例模式
原⽂链接:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。