springboot默认创建的bean是单实还是多例

转:https://blog.csdn.net/q1512451239/article/details/53122687

springboot默认创建的bean是单实还是多例

曾经面试的时候有面试官问我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中不定义属性,那么单例完全是安全的。下面给个例子说明下:

@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"),将其设置为多例模式

原文地址:https://www.cnblogs.com/wenhuang/p/9784419.html

时间: 2024-10-14 20:53:54

springboot默认创建的bean是单实还是多例的相关文章

springboot默认创建的bean是单实例

默认是单例 通过注解@Scope("prototype"),将其设置为多例模式 参考: 曾经面试的时候有面试官问我spring的controller是单例还是多例,结果我傻逼的回答当然是多例,要不然controller类中的非静态变量如何保证是线程安全的,这样想起似乎是对的,但是不知道(主要是我没看过spring的源码,不知道真正的内在意图)为什么spring的controller是单例的. 先看看spring的bean作用域有几种,分别有啥不同. spring bean作用域有以下5

Spring Bean注入/单例理解/循环依赖

理解循环依赖问题,首先明白spring有四种注入方式. 第一种,SET注入a类中持有b类的引用,并且a类有b的set方法.在bean中添加<property>标签即可注入.实质上是将b实例化,然后调用set方法注入. <bean id="a" class="com.qunar.pojo.StudentA" scope="singleton"> <property name="studentB" r

ABP示例程序-使用AngularJs,ASP.NET MVC,Web API和EntityFramework创建N层的单页面Web应用

本片文章翻译自ABP在CodeProject上的一个简单示例程序,网站上的程序是用ABP之前的版本创建的,模板创建界面及工程文档有所改变,本文基于最新的模板创建.通过这个简单的示例可以对ABP有个更深入的了解,每个工程里应该写什么样的代码,代码如何组织以及ABP是如何在工程中发挥作用的. 源文档地址:https://www.codeproject.com/Articles/791740/Using-AngularJs-ASP-NET-MVC-Web-API-and-EntityFram 源码可以

创建通用的表单校验逻辑库

表单校验一直是web开发中最基础,也是最不好做的一个环节.说是基础,相信多少从事web开发的人第一件事就是学习如果基于js.jQuery实现表单验证工作.在10年前,甚至是5年前,JavaScript还是被多数工程师轻视的一门语言,那时候很多人认为JavaScript充其量也就能完成一部分表单校验的工作.由此可知表单校验是多么基础的一件事情:说它不好做,是因为表单校验往往工作量极大,可以说是一个没太大技术含量但是很耗费体力的活,而且在一些对交互友好性要求较高的项目中,表单校验就更加费事了. 于是

SpringBoot拦截器中Bean无法注入(转)

这两天遇到SpringBoot拦截器中Bean无法注入问题.下面介绍我的思考过程和解决过程: 1.由于其他bean在service,controller层注入一点问题也没有,开始根本没意识到Bean无法注入是在拦截器中无效的问题,一直在查找注解指定的包在哪里配置的,然而却找不到配置,Springboot是用java类的形式加载配置的.在网络的某个角落看到这样的说法: SpringBoot项目的Bean装配默认规则是根据Application类所在的包位置从上往下扫描!"Application类&

配置和修改springboot默认国家化文件

SpringBoot默认国际化文件为:classpath:message.properties,如果放在其它文件夹中,则需要在application.properties配置属性spring.messages.basename: 在srpingboot自定义一个国家化文件: 1.在resources目录下创建myconfig.properties2.修改application.properties或者application.yml文件:        spring:          messa

Springboot默认数据库连接池及常用属性

Springboot默认数据库连接池为 Tomcat JDBC Pool ,常用的属性见下表: 属性 描述 默认值 defaultAutoCommit 连接池中创建的连接默认是否自动提交事务 驱动的缺省值 defaultReadOnly 连接池中创建的连接默认是否为只读状态 - defaultCatalog 连接池中创建的连接默认的 catalog - driverClassName 驱动类的名称 - username 数据库账户 - password 数据库密码 - maxActive 连接池

Spring源码学习-容器BeanFactory(五) Bean的创建-探寻Bean的新生之路

写在前面 上面四篇文章讲了Spring是如何将配置文件一步一步转化为BeanDefinition的整个流程,下面就到了正式创建Bean对象实例的环节了,我们一起继续学习吧. 2.初始化Bean对象实例 Resource resource = new ClassPathResource("beanFactory.xml"); BeanFactory beanFactory = new XmlBeanFactory(resource); Student student = beanFact

Nodejs express中创建ejs项目,解决express下默认创建jade,无法创建ejs问题

最近在看<Node.js开发指南>,看到使用nodejs进行web开发的时候,准备创建ejs项目遇到问题了, 书上命令为: ? 1 express -t ejs microblog 可是执行后,仍旧创建的是jade项目. 原来,express3.x,express4.x中创建ejs命令更新为: express -e microblog //即ejs,-j(即jade)  当然,最直接的,你也可以修改package.json里的定义来实现安装ejs. PS:建立工程过程 1.必须得安装expre