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 ...
随机推荐
- 小KING教你做android项目(二)---实现登陆页面并跳转和简单的注册页面
原文:http://blog.csdn.net/jkingcl/article/details/10989773 今天我们主要来介绍登陆页面的实现,主要讲解的就是涉及到的布局,以及简单的跳 ...
- Android音频捕获(录音)(转)
原文:http://www.yiibai.com/android/android_audio_capture.html Android有一个内置的麦克风,通过它可以捕获音频和存储,或在手机进行播放.有 ...
- HttpClient 以post的方式发送请求(由于请求参数太多所以改成以post提交表单的方式)
1:Util类方法 /** * 发送 Post请求 * * @param url * @param reqXml * @return */ public static String post(Stri ...
- MySQL : INSERT INTO SELECT
INSERT INTO wx_announcement_push ( title, content, STATUS, del_flag, user_login_name ) SELECT '大家好', ...
- spring mvc绑定参数之 类型转换 有三种方式:
spring mvc绑定参数之类型转换有三种方式: 1.实体类中加日期格式化注解(上次做项目使用的这种.简单,但有缺点,是一种局部的处理方式,只能在本实体类中使用.方法三是全局的.) @DateTim ...
- Python连载60-Tkinter布局、按钮以及属性详解
一.Tkinter 1.组件的大致使用步骤 (1)创建总面板 (2)创建面板上的各种组件: i.指定组件的父组件,即依附关系:ii.利用相应的属性对组件进行设置:iii.给组件安排布局. (3)同步 ...
- 观察者设计模式(C#委托和事件的使用)
观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新.在现实生活中的可见观察者模式,例如,微信中的订阅号,订阅博客和QQ微博中关注好友 ...
- C++函数的理解思考
函数指针调用方式 void testmy(int k) { cout << "testzhixing " <<k << endl; } int ...
- QQ企业通--客户端登陆模块设计---知识点
AutoValidate 枚举 确定控件在失去用户输入焦点时应如何验证其数据. 成员名称 说明 Disable 将不进行隐式验证.设置此值将不会妨碍对 Validate 或 ValidateChil ...
- ionic3记录之APP运行时网络判断
判断设备网路是否正常: 安装插件: ionic cordova plugin add cordova-plugin-network-information npm install --save@nat ...