Spring中Bean的作用域

     在配置文件中定义Bean时,用户不但可以配置Bean的属性值以及相互之间的依赖关系,还可以定义Bean的作用域。

     作用域将对Bean的生命周期和创建方式产生影响,在低版本的Spring中,仅有两个作用域:singleton 和 prototype。

     在Sprign2.0中,针对WebApplicationContext新添加了3个新的作用域:request,session,globalSession。

 

一、singleton和prototype

     在低版本的Spring中,由于仅有两个作用域:singleton 和 prototype,所以采用singleton="true|false"的配置方式,Spring为了向后兼容,依旧支持这种配置方式,不过Spring推荐采用新的配置方式:scope="作用域类型"。

    1.singleton作用域

    Spring以容器的方式提供天然的单实例模式功能,任何POJO无需编写特殊的 代码仅通过配置就可以想用单实例模式的大餐。

    因为Spring利用AOP和LocalThread的功能,对非线程安全的变量进行了特殊的处理,使这些非线程安全的类变成了线程安全的类。

<bean id="car1" class="spring.ioc.demo1.Car" scope="singleton"
        p:brand="spring注入-红旗001" 
        p:color="spring注入-紫色" 
        p:maxSpeed="520" />
public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
     //singleton的bean
        Car car1 = ctx.getBean("car1",Car.class);
        System.out.println("单例的car1:"+car1);
        car1.setBrand("改变");
        Car car2 = ctx.getBean("car1",Car.class);
        System.out.println("再次获取单例的car1:"+car2);
}

输出:

单例的car1:the car is:spring注入-红旗001, color is:spring注入-紫色, maxspeed is:520
再次获取单例的car1:the car is:改变, color is:spring注入-紫色, maxspeed is:520

     在默认的情况下,Spring的ApplicationContext容器在启动的时候,自动实例化所有的singleton的Bean并缓冲与容器中。

     a.这样首先对Bean提前的实例化操作会及早发现一些潜在的配置问题

     b.Bean将以缓存方式保存,当再次使用时无需再实例化了

     如果用户不希望在容器启动时实例化singleton的Bean,可以通过lazy-init属性进行控制:

<bean id="car1" class="spring.ioc.demo1.Car" scope="singleton"
        p:brand="spring注入-红旗001" 
        p:color="spring注入-紫色" 
        p:maxSpeed="520" 
                lazy-init="true"
/>

     lazy-init="true"的Bean在某些特殊情况下依旧会提前实例化:如果该Bean被其他需要提前实例化的Bean引用到。

 

     2.prototype作用域

     在默认情况下,Spring容器在启动时不实例化prototype的Bean,此外,Spring容器讲prototype的Bean交给调用者后,就不再管理它的生命周期。

<bean id="carPrototype" class="spring.ioc.demo1.Car" scope="prototype"
        p:brand="邦德" 
        p:color="黑色" 
        p:maxSpeed="110" />
public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
     //prototype的bean
        Car carPrototype1 = ctx.getBean("carPrototype",Car.class);
        System.out.println("多例的carPrototype:"+carPrototype1);
        carPrototype1.setBrand("改变");
        Car carPrototype2 = ctx.getBean("carPrototype",Car.class);
        System.out.println("再次获取多例的carPrototype:"+carPrototype2);
}

输出:

多例的carPrototype:the car is:邦德, color is:黑色, maxspeed is:110
再次获取多例的carPrototype:the car is:邦德, color is:黑色, maxspeed is:110

     每次getBean都将得到一个最新状态的Bean.

 

二、Web应用环境相关的Bean的作用域

     1.request作用域

<bean id="car" class="spring.ioc.demo1.Car" scope="request"
        p:brand="邦德" 
        p:color="黑色" 
        p:maxSpeed="110" />

     request作用域的Bean对应一个HTTP请求和生命周期,每次HTTP请求到carBean时,Spring容器创建一个新的carBean,请求处理完毕,销毁这个Bean.

     

     2.session作用域

<bean id="car" class="spring.ioc.demo1.Car" scope="session"
        p:brand="邦德" 
        p:color="黑色" 
        p:maxSpeed="110" />

     carBean的作用域将横跨整个HTTP Session,Session中所有的HTTP请求都将共享一个carBean,当HTTP Session结束后,实例才被销毁。

 

     3.globalSession作用域

<bean id="car" class="spring.ioc.demo1.Car" scope="globalSession"
        p:brand="邦德" 
        p:color="黑色" 
        p:maxSpeed="110" />在

     globalSession作用域类似于session作用域,不过仅在Portlet的web应用中使用。Portlet规范定义了全局Sesson的概念,它被组成portletweb应用的所有子portlet共享。如果不在Portlet的web应用中使用,globalSession自然就等价于session作用域了。

转载于:https://www.cnblogs.com/NicholasLee/archive/2012/07/14/2591559.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值