Spring入门之三-------SpringIoC之Scopes
一、singleton和prototype
public class Bean1 {
public Bean1() {
System.out.println(this.getClass().getSimpleName() + ":" + this.toString() + " has been created");
}
}
Bean1
1. singleton:
每个IoC容器只创建一个该类的Bean。
<bean id="bean1Singleton" class="com.imooc.springClass3.iocOthers.Bean1" scope="singleton"/>
public class BeanTest {
@Test
public void testBean() throws Exception {
for (int i = 0; i < 10; i++) {
Bean1 bean1Singleton = context.getBean("bean1Singleton", Bean1.class);
System.out.println("bean1Singleton = " + bean1Singleton);
}
}
}
输出
bean1Singleton = com.imooc.springClass3.iocOthers.Bean1@696da30b
bean1Singleton = com.imooc.springClass3.iocOthers.Bean1@696da30b
bean1Singleton = com.imooc.springClass3.iocOthers.Bean1@696da30b
......
可以看到,每个Bean对象的地址都是一样的。
2. prototype
每次从IoC容器中请求Bean都会创建一个新的实例,包括将Bean注入到另一个Bean中或通过Spring上下文执行getBean方法
<bean id="bean1Prototype" class="com.imooc.springClass3.iocOthers.Bean1" scope="prototype"/>
public class BeanTest {
@Test
public void testBean() throws Exception {
for (int i = 0; i < 10; i++) {
Bean1 bean1Prototype = context.getBean("bean1Prototype", Bean1.class);
System.out.println("bean1Prototype = " + bean1Prototype);
}
}
}
输出
Bean1:com.imooc.springClass3.iocOthers.Bean1@5f9b2141 has been created
bean1Prototype = com.imooc.springClass3.iocOthers.Bean1@5f9b2141
Bean1:com.imooc.springClass3.iocOthers.Bean1@247d8ae has been created
bean1Prototype = com.imooc.springClass3.iocOthers.Bean1@247d8ae
Bean1:com.imooc.springClass3.iocOthers.Bean1@48974e45 has been created
bean1Prototype = com.imooc.springClass3.iocOthers.Bean1@48974e45
......
可以看到,每个Bean对象的地址都是不同的。
二、request、session、application、websocket
只有在web环境下才可以使用这四个作用域,要引入web环境要求做如下配置(web.xml):
如果使用DispatcherServlet,则不需要增加其他任何配置,例如:
<servlet>
<servlet-name>SpringServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SpringServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
如果不使用DispatcherServlet,那么需要增加listener或filter:
(1)如果是Servlet 2.4以上
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
(2)如果是Servlet 2.4及以下
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
配置好了我们开始测试:
1. request
每个Bean的作用域为一个request请求,即每个request请求都会创建一个单独的实例。
@Controller
public class RequestScopeController { @GetMapping("testRequestScope")
@ResponseBody
public String test() {
return this.toString();
}
}
<bean id="testController" class="com.imooc.springClass3.iocOthers.RequestScopeController" scope="request"/>
运行tomcat,访问:http://127.0.0.1:8080/testRequestScope,刷新几次,可以看到每次刷新后创建的RequestScopeController实例都是不同的地址。
2. session
每个Bean的作用域为一个session会话,即每个session都会创建一个单独的实例
@Controller
public class SessionScopeController { @GetMapping("testSessionScope")
@ResponseBody
public String test() {
return this.toString();
}
}
<bean id="sessionScopeController" class="com.imooc.springClass3.iocOthers.SessionScopeController" scope="session"/>
运行tomcat,访问:http://127.0.0.1:8080/testRequestScope,刷新几次,可以看到每次刷新后创建的SessionScopeController实例都是一样的地址。但是当我们打开另外一个浏览器或重新打开当前浏览器再次访问该地址,可以看到SessionScopeController的实例的地址发生了变化
3. application
每个Bean的作用域为一个servletContext上下文,即每个servletContext都会创建一个单独的实例
@Controller
public class ApplicationScopeController { @GetMapping("testAppScope")
@ResponseBody
public String test() {
return this.toString();
}
}
<bean id="applicationScopeController" class="com.imooc.springClass3.iocOthers.ApplicationScopeController" scope="application"/>
运行tomcat,访问:http://127.0.0.1:8080/testRequestScope,刷新几次,可以看到每次刷新后创建的ApplicationScopeController实例都是一样的地址。即使我们打开另外一个浏览器或重新打开当前浏览器再次访问该地址,ApplicationScopeController的实例的地址也不会发生变化。
4. websocket
每个Bean的作用域为一个webSocket连接,即每个webSocket连接都会创建一个新的实例。
三、自定义scope以及SimpleThreadScope
1. 自定义scope
(1)定义一个Class实现org.springframework.beans.factory.config.Scope,本例中定义了一个MyScope,实现:每个Class最多可以生成两个实例。代码如下:
public class MyScope implements org.springframework.beans.factory.config.Scope {
private Map<String, Object> map = new ConcurrentHashMap<String, Object>();
public Object get(String s, ObjectFactory<?> objectFactory) {
if (map.containsKey(s + "0") && map.containsKey(s + "1")) {
return map.get(s + new Random().nextInt(2));
} else {
Object object = objectFactory.getObject();
if (!map.containsKey(s + "0")){
map.put(s + "0", object);
} else if (!map.containsKey(s + "1")) {
map.put(s + "1", object);
}
return object;
}
}
@Nullable
public Object remove(String s) {
Object object = null;
if (map.containsKey(s + "0") && map.containsKey(s + "1")) {
object = map.get(s + new Random().nextInt(2));
} else if (map.containsKey(s + "0")){
object = map.get(s + "0");
} else if (map.containsKey(s + "1")) {
object = map.get(s + "1");
}
map.remove(s + "0");
map.remove(s + "1");
return object;
}
public void registerDestructionCallback(String s, Runnable runnable) {
}
@Nullable
public Object resolveContextualObject(String s) {
return null;
}
@Nullable
public String getConversationId() {
return null;
}
}
(2)向Spring注册MyScope
<bean id="myScope" class="com.imooc.springClass3.iocOthers.MyScope"/>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="myScope" value-ref="myScope"/>
</map>
</property>
</bean>
(3)注册一个Bean使用MyScope作用域
<bean id="bean1MyScope" class="com.imooc.springClass3.iocOthers.Bean1" scope="myScope"/>
(4)测试
public class BeanTest {
@Test
public void testBean() throws Exception {
for (int i = 0; i < 10; i++) {
Bean1 bean1MyScope = context.getBean("bean1MyScope", Bean1.class);
System.out.println("bean1MyScope = " + bean1MyScope);
}
}
(5)输出
bean1MyScope = com.imooc.springClass3.iocOthers.Bean1@932bc4a
bean1MyScope = com.imooc.springClass3.iocOthers.Bean1@932bc4a
bean1MyScope = com.imooc.springClass3.iocOthers.Bean1@6bedbc4d
bean1MyScope = com.imooc.springClass3.iocOthers.Bean1@932bc4a
bean1MyScope = com.imooc.springClass3.iocOthers.Bean1@932bc4a
bean1MyScope = com.imooc.springClass3.iocOthers.Bean1@6bedbc4d
bean1MyScope = com.imooc.springClass3.iocOthers.Bean1@6bedbc4d
bean1MyScope = com.imooc.springClass3.iocOthers.Bean1@932bc4a
bean1MyScope = com.imooc.springClass3.iocOthers.Bean1@6bedbc4d
从输出结果可以看到只出现了两个不同的Bean地址,说明我们只创建了两个Bean实例。
2. SimpleThreadScope
每个Bean的作用域为一个线程,即每个线程都会创建一个Bean实例。
(1)注册SimpleThreadScope
<bean id="simpleThreadScope" class="org.springframework.context.support.SimpleThreadScope"/>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="simpleThreadScope" value-ref="simpleThreadScope"/>
</map>
</property>
</bean>
(2)注册一个Bean使用SimpleThreadScope作用域
<bean id="bean1SimpleThreadScope" class="com.imooc.springClass3.iocOthers.Bean1" scope="simpleThreadScope"/>
(3)测试
public class BeanTest {
@Test
public void testBean() throws Exception {
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
public void run() {
for (int i1 = 0; i1 < 10; i1++) {
Bean1 bean1SimpleThreadScope = context.getBean("bean1SimpleThreadScope", Bean1.class);
System.out.println("bean1SimpleThreadScope = " + bean1SimpleThreadScope);
}
}
}).start();
}
Thread.sleep(2000);
}
}
(4)输出:由于多线程并发,我们没有控制线程同步,所以输出结果可能出现混乱,所以我们就不贴输出结果了。
Spring入门之三-------SpringIoC之Scopes的更多相关文章
- Spring入门之五-------SpringIoC之通过注解实现
一.准备工作 创建一个Class注解@Configuration,如下例子: @Configuration // 该注解可理解为将当前class等同于一个xml文件 @ComponentScan(&q ...
- Spring入门之四-------SpringIoC之其他知识点
一.懒加载 public class Bean1 { public Bean1() { System.out.println(this.getClass().getSimpleName() + &qu ...
- Spring入门2. IoC中装配Bean
Spring入门2. IoC中装配Bean 20131125 前言: 上一节学习了Spring在JavaProject中的配置,通过配置文件利用BeanFactory和ApplicationConte ...
- Spring入门1. IoC入门实例
Spring入门1. IoC入门实例 Reference:Java EE轻量级解决方案——S2SH 前言: 之前学习过关于Spring的一点知识,曾经因为配置出现问题,而总是被迫放弃学习这些框架技术, ...
- SSM(spring mvc+spring+mybatis)学习路径——1-1、spring入门篇
目录 1-1 Spring入门篇 专题一.IOC 接口及面向接口编程 什么是IOC Spring的Bean配置 Bean的初始化 Spring的常用注入方式 专题二.Bean Bean配置项 Bean ...
- Spring入门及IoC的概念
Spring入门 Spring是一个轻量级的Java开发框架,最早由Robd Johnson创建,目的为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题,它是一个分层的JavaSE/EE轻量级开源 ...
- Spring入门学习(一)
SpringMVC基础平台补充(2016.03.03) 如果想要开发SpringMVC,那么前期依次安装好:JDK(jdk-8u74-windows-x64,安装后配置环境变量JAVA_HOME和CL ...
- VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)
VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)-软件开发-鸡啄米 http://www.jizhuomi.com/software/143.html 鸡啄米在上一讲中 ...
- Spring入门(10)-Spring JDBC
Spring入门(10)-Spring JDBC 0. 目录 JdbcTemplate介绍 JdbcTemplate常见方法 代码示例 参考资料 1. JdbcTemplate介绍 JdbcTempl ...
随机推荐
- 【PAT甲级】1038 Recover the Smallest Number (30 分)
题意: 输入一个正整数N(<=10000),接下来输入N个字符串,每个字符串包括至多8个字符,均为数字0~9.输出由这些字符串连接而成的最小数字(不输出前导零). trick: 数据点0只包含没 ...
- 敏捷团队协作:Confluence简易教程
0.Confluence简介 Confluence是一个企业级的Wiki软件,可用于在企业.部门.团队内部进行信息共享和协同编辑. 1.基础概念 Confluence的使用并不复杂,只需掌握如下几 ...
- Controller 层类
package com.thinkgem.jeesite.modules.yudengji.web; import java.util.Date; import javax.servlet.http. ...
- 「SDOI2013」森林
「SDOI2013」森林 传送门 树上主席树 + 启发式合并 锻炼码力,没什么好说的. 细节见代码. 参考代码: #include <algorithm> #include <cst ...
- 由前端登录验证,页面跳转,携带headers token引发的思考和尝试
目录 1 前言 2 我的实现方式与存在的问题 3 我想到的解决方案 3.1 前端跳转时携带headers{'token': token} 不就行了(经验证不可行) 3.2 前端跳转封装请求,携带hea ...
- 完全取代VC上原有的view
如果需要在这个VC上放置一个subviewA,作用相当于取代self.view,那么最好不要使用 [self.view addSubView: subviewA]; 而要使用 self.view = ...
- VUe for循环if 的使用和函数的使用 (笔记)
结果如图: 代码html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...
- 指定GPU运行python程序
一.命令行运行python程序时 1.首先查看哪些GPU空闲,nvidia-smi显示当前GPU使用情况. nvidia-smi 2.然后指定空闲的GPU运行python程序. CUDA_VISIBL ...
- 使用switch编写一个购物管理系统
在编写过程中,可能没有做到语句的精简,这个是需要解决的事. package nzcc4; import java.util.Scanner; public class Shopmain { publi ...
- AndroidQ强势来袭,国产自研系统还有未来吗?
我的小米8在重启时,屏幕上总会出现那句让人印象深刻的话--"Powered by android".事实上,几乎所有Android手机都会出现这几个单词--国产智能手机也不例外.这 ...