spring in action 学习笔记(四)bean的作用域

来源:互联网 发布:windows sdk如何安装 编辑:程序博客网 时间:2024/05/21 00:01

接着上几节的场景,选秀大赛需要观众,而观众入场是需要门票的,所以我们定义一个门票的领域模型

public class Ticket {    private Long id;    public Long getId() {        return id;    }    public void setId(Long id) {        this.id = id;    }    public static void main(String[] args) {        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/spring-beans.xml");        Ticket ticket = (Ticket) ctx.getBean("ticket");        System.out.println(ticket);        Ticket ticket1 = (Ticket) ctx.getBean("ticket");        System.out.println(ticket1);    }}

配置文件和之前一样,声明这个bean

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">    <!-- 声明了一个叫duke的Juggler类,并且构造器注入了15个豆袋子 -->    <bean id="duke" class="com.springinaction.ch02.Juggler">        <constructor-arg value="15"></constructor-arg>    </bean>    <!-- 声明了一首诗 -->    <bean id="sonnet29" class="com.springinaction.ch02.Sonnet29"/>    <bean id="poeticJuggler" class="com.springinaction.ch02.PoeticJuggler">        <constructor-arg value="6"/>        <constructor-arg ref="sonnet29"/>    </bean>    <bean id="stage" class="com.springinaction.ch02.Stage" factory-method="getInstance"/>    <bean id="ticket" class="com.springinaction.ch02.Ticket"/></beans>

运行main方法,输出如下

com.springinaction.ch02.Ticket@3efdk821
com.springinaction.ch02.Ticket@3efdk821

会发现我们什么时候获取ticket的bean,返回的对象都是一个,这是为什么呢。

原来,所有的Spring Bean默认都是单例singleton,当容器分配一个bean时(无论是通过装配还是调用容器的getBean()方法),它总是返回bean的同一个实例。但是,这里的场景,每个观众肯定拿的门票是独一无二,区别其他人的。spring支持每次请求的时候,都回去唯一的实例,而不是之前默认的那样每次请求获取的都是同一个实例。

我们只需要配置bean的scope属性为prototype即可。

    <bean id="ticket" class="com.springinaction.ch02.Ticket" scope="prototype"/>

输出如下:

com.springinaction.ch02.Ticket@5df115ce

com.springinaction.ch02.Ticket@7eceb790


在配置文件中再加入下面两个bean 声明

<bean id="ticket1" class="com.springinaction.ch02.Ticket"/><bean id="ticket2" class="com.springinaction.ch02.Ticket"/>
在ticket的main方法中,加入以下代码

Ticket tmp1 = (Ticket) ctx.getBean("ticket1");        System.out.println(tmp1);        Ticket tmp2 = (Ticket) ctx.getBean("ticket2");        System.out.println(tmp2);

会发现返回的是两个不同的ticket的对象,spring有关单例的概念限于spring上下文的范围内,不想真正的单例,在每个类加载器中保证只有一个ticket的对象,即只有一个实例。

spring的单例bean只能保证在每个应用上下文中只有一个bean的实例,他是基于bean的,同个类,声明了不同的bean,那么这些bean的对象就不会是同一个