`
xglv2013
  • 浏览: 37222 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

spring bean的scope实验

阅读更多
    众所周知,spring的bean在spring上下文的范围内默认是单例的,但通过将bean标签的scope属性显式的标记为prototype,可以使其变为非单例的。
    下面就写几行程序来验证一下这个结论,程序用到一个调用者接口Referer和被调用者接口Referee:
package refer;

public interface Referer 
{
	void order();
}

package refer;

public interface Referee
{
	void speak();
}

ChenReferer实现了调用者接口,guangReferee实现了被调用者接口:
package refer;

public class ChenReferer implements Referer
{
	public Referee guang;

	public Referee getGuang()
	{
		return guang;
	}

	public void setGuang(Referee guang)
	{
		this.guang = guang;
	}
	
	public void order()
	{
		System.out.println("I am chen and my address is: " + this.toString().split("@")[1]);
		guang.speak();
	}
}

package refer;

public class guangReferee implements Referee
{
	public void speak() {
		System.out.println("I am guang and my address is: " + this.toString().split("@")[1]);
	}
}

将调用者和被调用者的实现类的装配信息放入同一个包下的beans.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"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                     http://www.springframework.org/schema/context
                     http://www.springframework.org/schema/context/spring-context-3.0.xsd
                     http://www.springframework.org/schema/aop
                     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                     http://www.springframework.org/schema/tx
                     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
	<bean id="chen" class="refer.ChenReferer">
		<property name="guang" ref="guang" />
	</bean>
	
	<bean id="guang" class="refer.guangReferee">
	</bean>
</beans>

注意bean chen此时没有设置属性scope="prototype"
下面是主方法:
package refer;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestDemo 
{
	public static void main(String[] args)
	{
		ApplicationContext context = new ClassPathXmlApplicationContext("refer/beans.xml");
		Referer chen = (Referer) context.getBean("chen");
		Referer chen1 = (Referer) context.getBean("chen");
		
		chen.order();
		chen1.order();
	}
}

主方法加载了spring配置文件,第11行和第12行分别两次从spring容器中取出id为chen的bean,运行之,控制台显示:
I am chen and my address is: 259c259c
I am guang and my address is: 608a608a
I am chen and my address is: 259c259c
I am guang and my address is: 608a608a

我们可以看到两个chen的物理地址是相同的,虽然两次从容器中取bean,但是得到的只是同一个ChenReferer对象,证明其在上下文范围内的单例性。

下面再将beans.xml中bean chen加一个属性值scope的声明:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                     http://www.springframework.org/schema/context
                     http://www.springframework.org/schema/context/spring-context-3.0.xsd
                     http://www.springframework.org/schema/aop
                     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                     http://www.springframework.org/schema/tx
                     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
	<bean id="chen" class="refer.ChenReferer" scope="prototype">
		<property name="guang" ref="guang" />
	</bean>
	
	<bean id="ling" class="refer.LingReferer">
		<property name="guang" ref="guang" />
	</bean>
	
	<bean id="guang" class="refer.guangReferee">
	</bean>
</beans>

再运行主方法,结果为:
I am chen and my address is: 18561856
I am guang and my address is: 58cc58cc
I am chen and my address is: dc00dc0
I am guang and my address is: 58cc58cc

两次的chen物理地址是不同的,证明在第二次getBean方法调用时bean容器重新生成了一个ChenReferer对象。

同样的情况适用于被引用的对象,我们新加一个调用者LingReferer:
package refer;

public class LingReferer implements Referer
{
	public Referee guang;

	public Referee getGuang()
	{
		return guang;
	}

	public void setGuang(Referee guang)
	{
		this.guang = guang;
	}
	
	public void order()
	{
		System.out.println("I am ling and my address is: " + this.toString().split("@")[1]);
		guang.speak();
	}
}


beans.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"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                     http://www.springframework.org/schema/context
                     http://www.springframework.org/schema/context/spring-context-3.0.xsd
                     http://www.springframework.org/schema/aop
                     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                     http://www.springframework.org/schema/tx
                     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
	<bean id="chen" class="refer.ChenReferer" scope="prototype">
		<property name="guang" ref="guang" />
	</bean>
	
	<bean id="ling" class="refer.LingReferer">
		<property name="guang" ref="guang" />
	</bean>
	
	<bean id="guang" class="refer.guangReferee">
	</bean>
</beans>

此时bean guang的scope不是prototype的。
修改后的主方法:
package refer;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestDemo 
{
	public static void main(String[] args)
	{
		ApplicationContext context = new ClassPathXmlApplicationContext("refer/beans.xml");
		Referer chen = (Referer) context.getBean("chen");
		Referer ling = (Referer) context.getBean("ling");
		
		chen.order();
		ling.order();
	}
}

运行之,结果为:
I am chen and my address is: 371a371a
I am guang and my address is: 67146714
I am ling and my address is: 259c259c
I am guang and my address is: 67146714

虽然两个不同的调用者chen和ling分别都引用了guang,但是由于bean guang不是上下文单例的,所以它们引用的是同一个guangReferee对象。
再次更改beans.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"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                     http://www.springframework.org/schema/context
                     http://www.springframework.org/schema/context/spring-context-3.0.xsd
                     http://www.springframework.org/schema/aop
                     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                     http://www.springframework.org/schema/tx
                     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
	<bean id="chen" class="refer.ChenReferer" scope="prototype">
		<property name="guang" ref="guang" />
	</bean>
	
	<bean id="ling" class="refer.LingReferer">
		<property name="guang" ref="guang" />
	</bean>
	
	<bean id="guang" class="refer.guangReferee" scope="prototype">
	</bean>
</beans>

主方法不变,运行,得:
I am chen and my address is: b440b44
I am guang and my address is: d520d52
I am ling and my address is: 5ca45ca4
I am guang and my address is: 3aac3aac

由于bean guang被设置为上下文非单例的,所以在运行期,spring容器分别生成了两个不同的guangReferee对象,chen和ling分别引用了它们。
分享到:
评论

相关推荐

    spring bean 的作用域(scope)

    spring bean 的作用域(scope), SPringle bean的作用域

    详解Spring中bean的scope以后使用

    详解Spring中bean的scope以后使用,如何使用spring的作用域:

    创建SpringBean配置工具类

    创建SpringBean配置工具类(安全)如: &lt;bean id=... scope="prototype"&gt;&lt;/bean&gt;

    spring Bean的作用域之间有什么区别1

    Spring Bean 的作用域之间有什么区别:Bean的作用域: 可以通过scope 属性来指定bean的作用域 ①singleton: 默认值。当IOC容器

    Spring之scope讲解测试示例代码

    我的博客的spring之bean的Scope 的 示例代码。 包含了一个web工程(包括lib包)。但是里面也有可以执行的main函数。 环境是eclipse,spring 是 4.1.5

    JSP 中Spring Bean 的作用域详解

    Bean元素有一个scope属性,用于定义Bean的作用域,该属性有如下五个值: 1&gt;singleton: 单例模式,在整个spring IOC容器中,单例模式作用域的Bean都将只生成一个实例。一般Spring容器默认Bean的作用域为singleton ...

    Spring In Action-3.2@Scope单例、多例Bean

    Spring In Action-3.2@Scope单例、多例Bean,Spring In Action-3.2@Scope单例、多例Bean,Spring In Action-3.2@Scope单例、多例Bean,Spring In Action-3.2@Scope单例、多例Bean

    Spring中Scope为Request和Session的Bean了.docx

    首先定义一个简单的类 import lombok.Getter; import lombok.Setter; @Getter @Setter public class HelloMessageGenerator { private String message;... return getClass().getSimpleName() + "@" + Integer....

    Spring IOC Bean标签属性介绍(教学视频+源代码)

    Spring IOC Bean标签属性介绍 0.Bean标签属性介绍 1.0 新建一个Maven工程 1.1 pom.xml 1.2 实体类JavaBean 1.2.1 User类 1.3 当Scope="singleton"时 1.4 当 Scope="singleton" 且 lazy-init="true" 时 1.5 当scope=...

    Spring_0600_IOC_Bean_Scope

    NULL 博文链接:https://diaochenlong2.iteye.com/blog/1831285

    spring-scopes:自定义 Spring Bean 范围

    自定义 Spring Bean Scopes 用于默​​认设置不起作用的情况 可用范围 Route Scope - 提供每个路由执行范围的范围 页面范围 - 提供每页范围的范围 线程范围 - 提供每个线程范围的范围 继承的线程范围 - 提供每个线程...

    JAVA spring 系列案例50个和学习资料

    Spring系列第6篇:玩转bean scope,避免跳坑里!Spring系列第7篇:依赖注入之手动注入Spring系列第8篇:自动注入(autowire)详解,高手在于坚持Spring系列第9篇:depend-on到底是干什么的?Spring系列第10篇:...

    尚学堂_Spring_0600_IOC_Bean_Scope

    NULL 博文链接:https://listen-raining.iteye.com/blog/2128694

    07-IoC配置-scope属性

    &lt;bean scope=“singleton"&gt;&lt;/bean&gt; 取值: singleton:设定创建出的对象保存在spring容器中,是一个单例的对象(bean默认是单例) 单例的对象是在加载spring容器时就创建了,且此后你在同一个bean获取资源时,用...

    基于java的企业级应用开发:Bean的作用域.ppt

    在Spring配置文件中,可以使用&lt;bean&gt;元素的scope属性,将Bean的作用域定义成singleton。 singleton作用域 singleton是Spring容器默认的作用域,当Bean的作用域为singleton时,Spring容器就只会存在一个共享的Bean...

    spring学习心得

    创建对象的模式(使用范围):scope控制,可以使用singleton和prototype d.初始化:&lt;bean init-method=""/&gt; e.资源释放:&lt;bean destroy-method=""/&gt;仅对单例对象有效 (2)IoC概念 Inversion of Control 控制反转...

    springjdbc

    &lt;bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /&gt; &lt;!-- apache.dbcp连接池的配置 --&gt; &lt;bean id="dataSource" class="org.apache.commons.dbcp....

    maven3+struts2+spring+ibatis

    这个属于与Spring整合的问题,Spring容器在初始化对象的时候会根据bean的scope配置来考虑是重新建立一个对象,还是继续使用原来的对象,拿struts2的action的bean来说,如果scope这个参数没有配置,默认就是单例,即...

    吴天雄--Spring笔记.doc

    第一天内容:Spring框架简介(EJB、JMX、Spring核心功能、Spring模块详解、Spring重要概念(容器)、Spring容器初始化的整个流程、Spring后处理器),IOC详解,Spring环境搭建,Spring创建Bean的三种方式,scope属性...

    spring.doc

    Scope单例多例作用域拓展: 16 3.4.1 singleton(默认值) 16 3.4.2 prototype 17 3.4.3 Request 17 3.4.4 Session 18 3.4.5 Global session 18 3.4.6 指定Bean的初始化方法和销毁方法 18 Bean的初始化和销毁拓展: 18...

Global site tag (gtag.js) - Google Analytics