2021-07-02 11:29:44 晓掌柜 版权声明:本文为站长原创文章,转载请写明出处
Spring的Controller是单例还是多例?是线程安全的吗?怎么保证其线程安全?
上面这个算是在面试中的老生常谈的问题了,今天我们就围绕这个问题,做一个全面的解析。
Spring的Controller是单例的。我们可以通过下面的代码进行验证,
我们不管调用test接口多少次,创建实例这部分的控制台输出都是只有一次的。
/**
* @author XA
* date 2021/7/2 9:57
* description: 测试类controller
*/
@RestController
@Api(tags = "测试")
public class TestController {
private Integer i = 0;
private TestController(){
System.out.println("创建实例...");
}
@ApiOperation("test1")
@GetMapping("xaTest1")
public Integer xaTest1(){
System.out.println(++i);
return i;
}
@ApiOperation("test2")
@GetMapping("xaTest2")
public Integer xaTest2(){
System.out.println(++i);
return i;
}
@ApiOperation("test3")
@GetMapping("xaTest3")
public boolean xaTest3(){
System.out.println(++i);
return i%2 == 0;
}
}
我们通过postMan或者swagger调用测试发现,首次请求test1时返回的是1,再次调用test2时返回的是2。
两次的结果是不一致的,说明不是线程安全的!
这时候我们需要引入一个注解:@Scope("prototype")
然后我们在重复上述操作可以发现,两次的请求是一致的了
为了性能:不需要在每次使用时都new一个,减少资源消耗
① 不在controller中定义成员变量
② 不得不定义成员变量时,使用@Scope("prototype")声明为多例
① 单例模式下,Spring会初始化所有作用域下的Bean并统一管理。
② 配置了@Scope("prototype")后,有单例变成了原型模式,每次通过getBean时都会产生一个新的实例,
这时的Bean不再由Spring统一管理
PS: 通过下图我们也可以看到,配置了@Scope("prototype")后,每次请求都会创建一个实例的
更多精彩请持续关注:guangmuhua.com