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 ...
随机推荐
- JS 表单相关
var title = $("#subjects option:selected").text();
- 苹果系统 MacOS 安装根证书
12306 网上购票以及一些其他内部使用的系统,需要安装.cer扩展名的根证书的情况,windows安装较为简单大家也比较熟悉,使用mac安装根证书在此做下详细介绍. 当前以10.13.5版本为例,其 ...
- day20-Python运维开发基础(装饰器 / 类中的方法 / 类的方法变属性)
1. 装饰器 / 类中的方法 / 类的方法变属性 # ### 装饰器 """ 定义:装饰器用于拓展原来函数功能的一种语法,返回新函数替换旧函数 优点:在不更改原函数代码的 ...
- thymeleaf 学习笔记(转)
原文:http://blog.csdn.net/pdw2009/article/details/44410659 thymeleaf,我个人认为是个比较好的模板,性能也比一般的,比如freemaker ...
- 谈谈spring mvc与struts的区别
1.Struts2是类级别的拦截, 一个类对应一个request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上Spr ...
- Vue源码(下篇)
上一篇是mount之前的添加一些方法,包括全局方法gloal-api,XXXMixin,initXXX,然后一切准备就绪,来到了mount阶段,这个阶段主要是 解析template 创建watcher ...
- 「SDOI2009」HH的项链
「SDOI2009」HH的项链 传送门 数据加强了,莫队跑不过了. 考虑用树状数组. 先把询问按右端点递增排序. 然后对于每一种贝壳,我们都用它最右一次出现的位置计算答案. 具体细节看代码吧. 参考代 ...
- 为常用的块类型创建typedef
本文概要: 1.块类型的语法结构 2.使用C语言中的“类型定义”的特性.使用typedef关键字用于给块类型起个别名 3.使用typedef好处之一是,重构块的类型签名时只需要改一处就行了,避免遗留b ...
- 对简易网页版注册系统的制作(连接MySQL数据库)
一.基本需求 二.设计思路: 1.首先创建一个与数据库数据属性对应的类User,并添加get和set方法. 2.之后建立另一个类UserDao用于生成一条完整的数据对象. 3.再建立一个类DButil ...
- Python自动化运维的职业发展道路(暂定)
Python职业发展之路 Python自动化运维工程 Python基础 Linux Shell Fabric Ansible Playbook Zabbix Saltstack Puppet Dock ...