Spring5系列(六) | Controller到底线程安全么

简介: Spring5系列(六) | Controller到底线程安全么

本篇文章比较简单,主要介绍下关于对象的scope, 其实一直有一道比较经典的面试题,问的是springMVC中的Controller是单例的么?我们就从这道题来引申出来。


我们在学习java基础的时候,都会学到一种设计模式,叫做单例设计模式。什么叫做单例设计模式呢,就是要保证我们创建出来的对象永远只有一个。为什么要这样呢,主要目的就是为了合理的利用内存。有些比较重量级的对象其实创建一次就可以了,那么我们就可以使用单例设计模式。什么样的情况不能使用单例呢,那就是存在线程安全的问题的类,或者说存在共享资源可能被多个线程进行操作时,就不能使用单例设计模式。关于单例设计模式的实现方式这里就不展开了。


我们前面在讲解FactoryBean这个接口的时候,提到过里边有三个需要实现的方法,最常用的方法是getObject(),这个也是最核心的方法,用来获取复杂对象。其中还有一个方法叫做boolean isSingleton();这个方法返回布尔类型值,如果返回结果为true, 代表会返回一个单例对象,也就是多次获取都是同一个对象。如果返回的false, 多次获取,每次都是新的对象。这是FactoryBean为我们提供的方法,那么我们正常的被spring管理的对象能否像isSingleton() 方法一样,可以控制对象的创建次数呢。当然是可以的,通过<bean> 标签中的scope属性来指定。我们以之前的User类为例。


<beanid="user"class="com.xxx.User"scope="singleton"/>


这个时候我们创建出来的对象就是单例的,不管调用多少次,得到的都是同一个对象。我们可以在测试类中演示。


ApplicationContextctx=newClassPathXmlApplicationContext("/applicationContext.xml");
Useru1= (User)ctx.getBean("user");
Useru2= (User)ctx.getBean("user");
System.out.println(u1);
System.out.println(u2);


观察结果可以发现打印的地址值是一样的,代表是同一个对象。那么如果我们想要非单例对象,也就是每次获取都是一个新的对象该如何处理呢,只需把scope改为prototype。


<beanid="user"class="com.xxx.User"scope="prototype"/>


再次执行上面的测试方法打印地址不同,说明是不同对象。

这里要注意,scope的默认值是singleton。也就是在不指定scope的情况下得到的也是单例对象。


那么对于使用工厂创建的对象如何指定呢。

  1. 对于实现FactoryBean的工厂,通过实现isSingleton() 方法指定
  2. 对于实例工厂和静态工厂,也是通过scope来指定。

如果不清楚什么是实例工厂和静态工厂,快去看下我的上一篇文章。 那么我们在来讲解下,到底什么样的对象用单例,什么时候不用单例呢?


单例的,一般就是比较耗资源的,且没有线程安全问题的,比如

  1. sqlSessionFactory
  2. DAO
  3. Service


对于非单例的:像数据库的连接和会话,对于每个线程之间需要有一定隔离性,否则事务胡乱提交会产生问题的,就需要使用非单例。比如:

  1. Connection
  2. SqlSession | Session
  3. Struts2 ACtion


好了最后,我们再回到最初的问题,spring中的Controller是单例的么? 答案是肯定的,因为Controller也是spring管理的一个Bean, 默认就是单例的。那继续提问, Controller是线程安全的么, 其实并不是,由于单例的模式,就会被多个线程同时使用,所以我们要尽量避免在Controller中定义成员变量,以免引发线程安全问题。

好了本篇文章就介绍到这里。喜欢的话,收藏加关注,学习不迷路。


目录
相关文章
|
4天前
|
人工智能 JSON 前端开发
【Spring boot实战】Springboot+对话ai模型整体框架+高并发线程机制处理优化+提示词工程效果展示(按照框架自己修改可对接市面上百分之99的模型)
【Spring boot实战】Springboot+对话ai模型整体框架+高并发线程机制处理优化+提示词工程效果展示(按照框架自己修改可对接市面上百分之99的模型)
|
7月前
|
XML 安全 Java
Spring框架中的单例bean是线程安全的吗?阿里一面
在 Spring 框架中,Bean 是指由 Spring IoC(Inversion of Control)容器管理的组件或对象。Bean 是 Spring 中最基本的构建块,它们由 Spring 容器实例化、组装和管理。
57 0
|
4天前
|
安全 Java Spring
Spring框架中的单例Bean是线程安全的吗?
Spring框架中的单例Bean是线程安全的吗?
10 1
|
4天前
|
监控 Java Spring
Spring Boot中一般如何使用线程池?
在Spring Boot应用程序中,合理地使用线程池可以有效地提高系统的性能和并发处理能力。本文将深入探讨Spring Boot中如何一般性地使用线程池,包括线程池的配置、使用方式以及一些最佳实践。
25 0
|
4天前
|
安全 Java Spring
Spring 的 Controller 是单例还是多例?怎么保证并发的安全
Spring 的 Controller 是单例还是多例?怎么保证并发的安全
19 0
|
4天前
|
安全 Java Spring
Spring 的 Controller 是单例还是多例?怎么保证并发的安全
Spring 的 Controller 是单例还是多例?怎么保证并发的安全
13 0
|
4天前
|
JavaScript Java API
spring boot使用异步多线程
一文讲清楚spring boot如何结合异步多线程实现文件的导出这类耗时间的操作优化以及常用的场景,了解异步思想
44 0
spring boot使用异步多线程
|
4天前
|
安全 Java 调度
Spring中的多线程魔法:探索@Async注解的妙用
Spring中的多线程魔法:探索@Async注解的妙用
43 0
|
9月前
|
JSON 前端开发 Java
Spring 注解之@RestController与@Controller的区别
Spring 注解之@RestController与@Controller的区别
71 0
|
4天前
|
Java Spring
使用spring boot的@Async实现异步调用和线程池复用
使用spring boot的@Async实现异步调用和线程池复用