`
xglv2013
  • 浏览: 38190 次
  • 性别: 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的生命周期

    - **XML配置**:在传统的Spring应用中,Bean的定义通常写在XML配置文件中,如`springbean-xml`中的配置。 - **注解配置**:使用`@Component`,`@Service`,`@Repository`和`@Controller`注解标记类,配合`@...

    spring bean life cycle

    `scope`属性可以设定Bean的作用域,如单例(singleton)或多例(prototype)。 总的来说,Spring Bean生命周期的理解和灵活运用,能帮助我们更好地控制Bean的行为,实现更高效、更可控的依赖管理和资源管理。通过...

    Spring Bean 加载顺序 .

    在注册时,Spring会根据@Bean、@Scope等注解确定Bean的作用域。默认情况下,Bean是单例(Singleton),但也可以配置为原型(Prototype)或其他作用域。 4. **Bean的依赖解析**: Spring会分析Bean之间的依赖关系...

    详解Spring中bean的scope以后使用

    在Spring框架中,Bean的作用域(scope)是一项非常重要的特性,它决定了Bean实例的生命周期和管理方式。正确理解和运用Bean的作用域对于优化应用程序性能、简化开发流程具有重要意义。本文将详细介绍Spring中不同...

    创建SpringBean配置工具类

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

    Spring之scope讲解测试示例代码

    在Spring框架中,`scope`是一个非常重要的概念,它决定了Bean的生命周期和实例化策略。在Spring中,Bean的scope主要有以下几种: 1. **singleton(单例)**:这是默认的scope,每个容器中只有一个实例。无论多少次...

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

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

    Spring Bean 的生命周期

    如果配置了`@Scope("prototype")`,每次请求都会创建一个新的Bean。 2. **属性注入**:Spring容器将根据Bean定义中的属性值、setter方法或构造函数参数来设置Bean的依赖。这包括了基本类型、其他Bean引用、集合类型...

    Spring Bean生命周期&BeanDefinitions1

    默认情况下,Bean的scope为"singleton",表示Spring容器只创建一个实例,并将其缓存。如果scope设为"prototype",每次请求都会创建一个新的Bean实例。 7. **销毁**:当容器关闭时,如果是"singleton"作用域的Bean,...

    Spring之核心容器bean

    Spring框架是Java开发中的一个核心库,主要用于管理对象(通常称为bean)的生命周期和依赖关系。在本篇文章中,我们将深入探讨Spring的核心容器及其bean的概念,以帮助你更好地理解和使用这个强大的工具。 **Spring...

    线程中获取spring 注解bean

    6. **RequestScope**:在Web应用中,如果bean需要在一次HTTP请求的生命周期内保持一致,可以使用`@Scope("request")`。这样,每次请求都会创建新的bean实例,而不会影响其他线程。 理解并熟练掌握这些方法,有助于...

    第四章 Spring Bean基础1

    Spring Bean 是 Spring 框架的核心概念,它代表了应用程序中的一个对象,这个对象可以被 Spring 容器管理,包括创建、初始化、装配、销毁等生命周期过程。在 Spring 中,Bean 定义是由 `BeanDefinition` 接口来表示...

    尚学堂_Spring_0600_IOC_Bean_Scope

    标题中的“Spring_0600_IOC_Bean_Scope”涉及到的是Spring框架中的核心概念——控制反转(Inversion of Control, 简称IOC)以及Bean的作用域(Scope)。在这个主题下,我们将深入探讨Spring如何通过IOC管理Bean的...

    粗略实现spring创建bean

    "粗略实现spring创建bean"这个主题主要涉及到Spring如何初始化、配置以及管理Java对象,也就是我们所说的Bean。下面我们将深入探讨Spring Bean的生命周期、配置方式以及相关API。 1. Spring Bean 的生命周期 - ...

    Spring中与Bean相关的接口

    默认情况下,Bean是单例(Singleton),但在`@Scope`注解的帮助下,我们可以创建原型(Prototype)、会话(Session)或请求(Request)作用域的Bean。 最后,`AutowireCandidateResolver`和`BeanFactoryAware`接口...

    详解Spring中Bean的生命周期和作用域及实现方式

    在配置Bean时,可以使用scope参数来指定Bean的作用域。 三、Bean的实现方式 Spring框架提供了多种方式来实现Bean,例如使用XML配置文件、使用Annotation配置等。 1. 使用XML配置文件:可以在XML配置文件中配置...

    JSP 中Spring Bean 的作用域详解

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

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

    在Spring框架中,`Scope`是一个关键的概念,用于定义Bean的作用域。在给定的文档中,主要讨论了两种特定的Bean作用域:`Request`和`Session`。这两个作用域在Web应用开发中尤其重要,因为它们与HTTP请求和会话紧密...

Global site tag (gtag.js) - Google Analytics