通俗易懂spring之singleton和prototype
关于spring bean作用域,基于不同的容器,会有所不同,如BeanFactory和ApplicationContext容器就有所不同,在本篇文章,主要讲解基于ApplicationContext容器的bean作用域。
关于bean的作用域,在spring中,主要包括singleton,prototype,session,request,global,本篇文章主要讲解常用的两种,即:singleton和prototype.
一 singleton
singleton为单例模式,即scope="singleton"的bean,在容器中,只实例化一次。
dao示例代码:
package com.demo.dao;
public class UserDao {
public UserDao(){
System.out.println("UserDao 无参构造函数被调用");
}
//获取用户名
public String getUserName(){
//模拟dao层
return "Alan_beijing";
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.demo.dao.UserDao" id="userDao" scope="singleton"/>
</beans>
test:
public class MyTest {
@Test
public void test(){
//定义容器并初始化
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//定义第一个对象
UserDao userDao = applicationContext.getBean(UserDao.class);
System.out.println(userDao.getUserName());
//定义第二个对象
UserDao userDao2 = (UserDao) applicationContext.getBean("userDao");
System.out.println(userDao2.getUserName());
//比较两个对象实例是否是同一个对象实例
System.out.println("第一个实例:"+userDao+"\n"+"第二个实例:"+userDao2);
}
}
测试结果:

分析:在测试代码中,将bean定义为singleton,并先后2次通过ApplicationContext的getBean()方法获取bean(userDao),却返回相同的实例对象:com.demo.dao.UserDao@27a5f880,仔细观察,虽然获取bean两次,但是UserDao的无参构造函数却只被调用一次,这也证明了在容器中,singleton实际只被实例化一次,需要注意的是,Singleton模式的bean,ApplicationContext加载bean时,就实例化了bean。
定义bean:

测试结果:
如下代码只是加载bean,却没调用getBean方法获取bean,但UserDao却被调用了一次,即实例化。

二 prototype
prototype即原型模式,调用多少次bean,就实例化多少次。
将singleton代码改为原型
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.demo.dao.UserDao" id="userDao" scope="prototype"/>
</beans>
测试代码与singleton一样,但结果却不一样:

分析:通过测试结果,不难发现,调用两次bean,就实例化两次UserDao对象,且对象不一样,需要注意的是,prototype类型的bean,只有在获取bean时,才会实例化对象。
三 singleton和prototype区别
(1)singleton在容器中,只被实例化一次,而prototype在容器中,调用几次,就被实例化几次;
(2)在AppplicationContext容器中,singleton在applicaitonContext.xml加载时就被预先实例化,而prototype必须在调用时才实例化
singleton:
定义bean:

测试:

prototype:
定义bean:

测试:不调用

测试:调用

4.singleton比prototype消耗性能,在web开发中,推荐使用singleton模式,在app开发中,推荐使用prototype模式。
四 版权区
转载博客,必须注明博客出处
博客园:http://www.cnblogs.com/wangjiming/ (侧重.NET)
CSDN:https://blog.csdn.net/u010228798 (侧重JAVA)
如您有新想法,欢迎提出,邮箱:2098469527@qq.com
专业.NET之家技术QQ群:490539956
专业化Java之家QQ群:924412846
有问必答QQ群:2098469527
一对一技术辅导QQ:2098469527
通俗易懂spring之singleton和prototype的更多相关文章
- [Spring Boot] Singleton and Prototype
When we use Bean to do autowired, it actually use singleton, so even we create multi instanses, they ...
- spring中scope的prototype与singleton区别
最近在研究单例模式,突然想起项目中以下配置,scope="singleton" 和 scope="prototype"到底有何区别呢?以下做下简要分析. < ...
- Singleton and Prototype Bean Scope in Spring
Scope描述的是Spring容器如何新建Bean的实例的. 1> Singleton: 一个Spring容器只有一个Bean的实例,此为Spring的默认配置,全容器共享一个实例. 2> ...
- spring中bean的作用域属性singleton与prototype的区别
1.singleton 当一个bean的作用域设置为singleton, 那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会 ...
- 【Spring】bean的作用域(@Scope) - singleton、prototype
已知spring 3+已拥有多种不同的作用域: singleton(默认).prototype.request.session.global session.(参考: spring中scope作用域( ...
- [Spring] Bean Scope Singleton cs Prototype
We can define a class to be Singleton or Prototype. If the class was defined as Prototype, then ever ...
- singleton和prototype的区别
singleton作用域:当把一个Bean定义设置为singleton作用域是,Spring IoC容器中只会存在一个共享的Bean实例,并且所有对Bean的 请求,只要id与该Bean定义相匹配,则 ...
- 辨析 singleton 和 prototype
<bean id="person1" class="com.bean.life.Person"> <property name="n ...
- 转:spring mvc 设置@Scope("prototype")
spring中bean的scope属性,有如下5种类型: singleton 表示在spring容器中的单例,通过spring容器获得该bean时总是返回唯一的实例prototype表示每次获得bea ...
随机推荐
- Marvelous Mazes UVA - 445
#include<iostream> #include<stdio.h> #include<string> #include<cstring> #def ...
- 树莓派4B安装64位Linux(不用显示器键盘鼠标)
入手了树莓派4B,我对它的定位是作为一个Docker实验环境,平时用到的镜像多为Java服务端常用的技术.以及自己作的Java应用镜像,因此宿主机需要64位操作系统,而树莓派官方操作系统只有32位的, ...
- gitlab版本管理小白入门
在新公司入职已经一周了,由于刚好在版本空档期,没有什么开发任务,就自己熟悉熟悉代码什么的. 目前公司用的是git,原来公司用的是svn,今天就记录下从小白入门. gitlab分布式版本管理,理论介绍就 ...
- ASP.NET Core结合Nacos来完成配置管理和服务发现
目录 前言 Nacos的简介 启动Nacos 配置管理 服务发现 写在最后 前言 今年4月份的时候,和平台组的同事一起调研了一下Nacos,也就在那个时候写了.net core版本的非官方版的SDK. ...
- 【Offer】[55-1] 【二叉树的深度】
题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 输入一棵二叉树的根节点,求该树的深度.从根节点到叶节点依次经过的节点(含根.叶节点)形成树的一条路径,最长路径的长度为树的深度. 牛客网 ...
- 脱离脚手架来配置、学习 webpack4.x (一)基础搭建项目
序 现在依旧记得第一次看到webpack3.x 版本配置时候的状态 刚开始看到这些真的是一脸懵.希望这篇文章能帮到刚开始入门的同学. webpack 是什么? webpack是一个模块化打包工具,w ...
- jps虚拟机进程状态工具
jps(JVM Process Status Tool) jps工具可以列出正在运行的虚拟机进程,并显示虚拟机执行主类名称以及这些进程的本地虚拟机唯一ID(Local Virtual Machine ...
- Python中使用pip安装库时提示:远程主机强迫关闭了一个现有的连接
场景 在cmd中使用pip install moviepy时,需要安装一些依赖库,很长时间后提示: 远程主机中断了一个现有的连接. 原因是默认镜像源下载过慢,将其修改为国内或者设置安装时的源. 这里以 ...
- Spring Boot2 系列教程(六)自定义 Spring Boot 中的 starter
我们使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中.Starter 为我们带来了众多的自动化配置,有了这些自动化配置,我们可以不费吹灰之力就能搭建一个生产级开发环境,有的小 ...
- response向客户端写入数据
1.写入文字: protected void doGet(HttpServletRequest request, HttpServletResponse response) throws Servle ...