众所周知,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), SPringle bean的作用域
详解Spring中bean的scope以后使用,如何使用spring的作用域:
创建SpringBean配置工具类(安全)如: <bean id=... scope="prototype"></bean>
Spring Bean 的作用域之间有什么区别:Bean的作用域: 可以通过scope 属性来指定bean的作用域 ①singleton: 默认值。当IOC容器
我的博客的spring之bean的Scope 的 示例代码。 包含了一个web工程(包括lib包)。但是里面也有可以执行的main函数。 环境是eclipse,spring 是 4.1.5
Bean元素有一个scope属性,用于定义Bean的作用域,该属性有如下五个值: 1>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
首先定义一个简单的类 import lombok.Getter; import lombok.Setter; @Getter @Setter public class HelloMessageGenerator { private String message;... return getClass().getSimpleName() + "@" + Integer....
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=...
NULL 博文链接:https://diaochenlong2.iteye.com/blog/1831285
自定义 Spring Bean Scopes 用于默认设置不起作用的情况 可用范围 Route Scope - 提供每个路由执行范围的范围 页面范围 - 提供每页范围的范围 线程范围 - 提供每个线程范围的范围 继承的线程范围 - 提供每个线程...
Spring系列第6篇:玩转bean scope,避免跳坑里!Spring系列第7篇:依赖注入之手动注入Spring系列第8篇:自动注入(autowire)详解,高手在于坚持Spring系列第9篇:depend-on到底是干什么的?Spring系列第10篇:...
NULL 博文链接:https://listen-raining.iteye.com/blog/2128694
<bean scope=“singleton"></bean> 取值: singleton:设定创建出的对象保存在spring容器中,是一个单例的对象(bean默认是单例) 单例的对象是在加载spring容器时就创建了,且此后你在同一个bean获取资源时,用...
在Spring配置文件中,可以使用<bean>元素的scope属性,将Bean的作用域定义成singleton。 singleton作用域 singleton是Spring容器默认的作用域,当Bean的作用域为singleton时,Spring容器就只会存在一个共享的Bean...
创建对象的模式(使用范围):scope控制,可以使用singleton和prototype d.初始化:<bean init-method=""/> e.资源释放:<bean destroy-method=""/>仅对单例对象有效 (2)IoC概念 Inversion of Control 控制反转...
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> <!-- apache.dbcp连接池的配置 --> <bean id="dataSource" class="org.apache.commons.dbcp....
这个属于与Spring整合的问题,Spring容器在初始化对象的时候会根据bean的scope配置来考虑是重新建立一个对象,还是继续使用原来的对象,拿struts2的action的bean来说,如果scope这个参数没有配置,默认就是单例,即...
第一天内容:Spring框架简介(EJB、JMX、Spring核心功能、Spring模块详解、Spring重要概念(容器)、Spring容器初始化的整个流程、Spring后处理器),IOC详解,Spring环境搭建,Spring创建Bean的三种方式,scope属性...
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...