一、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的更多相关文章

  1. Spring入门之五-------SpringIoC之通过注解实现

    一.准备工作 创建一个Class注解@Configuration,如下例子: @Configuration // 该注解可理解为将当前class等同于一个xml文件 @ComponentScan(&q ...

  2. Spring入门之四-------SpringIoC之其他知识点

    一.懒加载 public class Bean1 { public Bean1() { System.out.println(this.getClass().getSimpleName() + &qu ...

  3. Spring入门2. IoC中装配Bean

    Spring入门2. IoC中装配Bean 20131125 前言: 上一节学习了Spring在JavaProject中的配置,通过配置文件利用BeanFactory和ApplicationConte ...

  4. Spring入门1. IoC入门实例

    Spring入门1. IoC入门实例 Reference:Java EE轻量级解决方案——S2SH 前言: 之前学习过关于Spring的一点知识,曾经因为配置出现问题,而总是被迫放弃学习这些框架技术, ...

  5. SSM(spring mvc+spring+mybatis)学习路径——1-1、spring入门篇

    目录 1-1 Spring入门篇 专题一.IOC 接口及面向接口编程 什么是IOC Spring的Bean配置 Bean的初始化 Spring的常用注入方式 专题二.Bean Bean配置项 Bean ...

  6. Spring入门及IoC的概念

    Spring入门 Spring是一个轻量级的Java开发框架,最早由Robd Johnson创建,目的为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题,它是一个分层的JavaSE/EE轻量级开源 ...

  7. Spring入门学习(一)

    SpringMVC基础平台补充(2016.03.03) 如果想要开发SpringMVC,那么前期依次安装好:JDK(jdk-8u74-windows-x64,安装后配置环境变量JAVA_HOME和CL ...

  8. VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)

    VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)-软件开发-鸡啄米 http://www.jizhuomi.com/software/143.html   鸡啄米在上一讲中 ...

  9. Spring入门(10)-Spring JDBC

    Spring入门(10)-Spring JDBC 0. 目录 JdbcTemplate介绍 JdbcTemplate常见方法 代码示例 参考资料 1. JdbcTemplate介绍 JdbcTempl ...

随机推荐

  1. Jlink不报错的方法

    https://blog.csdn.net/yekui6254/article/details/85272767 方法:安装最新的jlink驱动,按下面网址下载 OllyDBG软件,根据上面说的方法修 ...

  2. scala命令行界面:help

    :help 查看所有可用命令 scala> :helpAll commands can be abbreviated, e.g., :he instead of :help.:edit < ...

  3. AJAX请求返回JSON数据动态生成html

    1:DeliveryPersonVO对象 package com.funcanteen.business.entity.delivery.vo; import java.util.List; impo ...

  4. Linux centosVMware shell中的函数、shell中的数组、

    一.shell中的函数 函数就是把一段代码整理到了一个小单元中,并给这个小单元起一个名字,当用到这段代码时直接调用这个小单元的名字即可. 格式: function _name() { command ...

  5. Linux centosVMware NFS exportfs命令、NFS客户端问题、FTP介绍、使用vsftpd搭建ftp

    一.exportfs命令 常用选项 -a 全部挂载或者全部卸载 -r 重新挂载 -u 卸载某一个目录 -v 显示共享目录 以下操作在服务端上 vim /etc/exports //增加 /tmp/ 1 ...

  6. springboot发送email邮件

    添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>sp ...

  7. 《算法图解》[美] Aditya Bhargava(作者)epub+mobi

    内容简介 本书示例丰富,图文并茂,以让人容易理解的方式阐释了算法,旨在帮助程序员在日常项目中更好地发挥算法的能量.书中的前三章将帮助你打下基础,带你学习二分查找.大O表示法.两种基本的数据结构以及递归 ...

  8. vs2015中安装cplex攻略以及解决丢失cplex.dll问题

    转:http://blog.sina.com.cn/s/blog_61f0374801014swp.html 按:相信配置过CPLEX的人大多有过痛苦而难忘的经历,本人亦不例外,纠结挣扎了一个下午加一 ...

  9. Mybatis入门(四)配置优化(一)

    这一章主要实验Mybatis的引入外部配置文件,属性(properties)这个属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素 ...

  10. 072、Java面向对象之定义构造方法

    01.代码如下: package TIANPAN; class Book { // 定义一个新的类 public Book() { // 构造方法 System.out.println("* ...