spring bean的scope实验_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > spring bean的scope实验

spring bean的scope实验

 2013/9/2 16:33:47  xglv2013  程序员俱乐部  我要评论(0)
  • 摘要:众所周知,spring的bean在spring上下文的范围内默认是单例的,但通过将bean标签的scope属性显式的标记为prototype,可以使其变为非单例的。下面就写几行程序来验证一下这个结论,程序用到一个调用者接口Referer和被调用者接口Referee:packagerefer;publicinterfaceReferer{voidorder();}packagerefer;publicinterfaceReferee{voidspeak();
  • 标签:Spring
    众所周知,spring的bean在spring上下文的范围内默认是单例的,但通过将bean标签的scope属性显式的标记为prototype,可以使其变为非单例的。
    下面就写几行程序来验证一下这个结论,程序用到一个调用者接口Referer和被调用者接口Referee:
class="java" name="code">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分别引用了它们。
发表评论
用户名: 匿名