Spring-bean的作用域
在大多数情况下,单例bean是很理想的方案。初始化和垃圾回收对象实例所带来的的成本只留给一些小规模任务,在这些任务中,让对象保持无状态并且在应用中反复重用这些对象可能并不合理。在这种情况下,将class声明为单例的bean会被污染,稍后重用的时候会出现意想不到的问题。
Spring定义了多种作用域,可以基于这些作用域创建bean,包括:
- 单例(singleton):在整个应用中,只创建bean的一个实例。
- 原型(prototype):每次注入或者通过Spring应用上下文获取的时候,都会创建一个新的实例。
- 会话(session):在Web应用中,为每个会话创建一个bean实例。
- 请求(request):在Web应用中,为每个请求创建一个bean实例。
单例是默认的作用域,如果选择其他作用域,要使用@Scope注解,它可以与@Component或@Bean一起使用:
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope; @Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Notepad{...}
当然也可以在@Bean下使用,参数可以直接写字符串prototype,singleton等,但并没有上述方式安全。
在xml模式中,可以在bean的属性中添加scope="prototype":
<bean id="notepad" class="..." scope="prototype"/>
使用会话和请求作用域
使用会话作用域的bean最合适的莫过于购物车了,一个用户用一个购物车,而不是共用,或者因商品种类不同而创造无用的购物车。因为它与给定的用户关联性最大。示例如下:
package soundSystem; import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext; @Component
@Scope(value=WebApplicationContext.SCOPE_SESSION,proxyMode=ScopedProxyMode.INTERFACES)
public class JDShoppingCart implements ShoppingCart{
public ShoppingCart getJDShoppingCart(){
return new JDShoppingCart();
}
}
这里,我们将value设置成了WebApplicationContext中的SCOPE_SESSION常量(它的值是session)。表明为Web应用中的每个会话创建一个ShoppingCart。这会创建多个ShoppingCart实例,但对于给定的会话,只创建一个实例。也就是说,在当前会话相关的操作中,ShoppingCart是单例的。
要注意的是,还有一个代理模式的属性,它被设置成ScopedProxyMode.INTERFACES。这个属性解决了讲会话或请求作用域的bean注入到单例bean中所遇到的问题。在描述proxyMode属性之前,我们先来看看proxyMode所解决问题的场景。假如要将ShoppingCart bean注入到单例StoreService bean的Setter方法中:
package soundSystem; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; @Component
public class StoreService {
private ShoppingCart shoppingCart; @Autowired
public void setShoppingCart(ShoppingCart shoppingCart) {
this.shoppingCart = shoppingCart;
}
}
因为StoreService是一个单例的bean,会在Spring应用上下文加载的时候创建。当它创建的时候,Spring会试图将ShoppingCart bean注入到setter方法中,但是ShoppingCart bean是会话作用域的,此时并不存在,直到某个用户进入系统,创建了会话之后,才会出现ShoppingCart实例。
另外,系统中将会有多个ShoppingCart实例:每个用户一个。我们并不想让Spring注入某个固定的ShoppingCart实例到StoreService中。我们希望的是当StoreService处理购物车功能时,它所使用的ShoppingCart实例恰好是当前会话所对应的那个。
所以Spring并不会将实际的ShoppingCart bean注入到StoreService中,Spring会注入到一个ShoppingCart bean的代理,这个代理会暴露与ShoppingCart相同的方法,所以StoreService会认为它是一个购物车。但是当StoreService调用ShoppingCart的方法时,代理会对其进行懒解析并将调用委托给会话作用域内真正的ShoppingCart bean。
现在,proxyMode被设置成ScopedProxyMode.INTERFACE常量,表明这个代理要实现ShoppingCart接口,并将调用委托给实现bean。如果需要实现类,则设置为ScopedProxyMode.TARGET_CLASS即可。
xml模式下配置代理模式
<bean id="jDShoppingCart" class="soundSystem.JDShoppingCart" scope="session">
<aop:scoped-proxy/>
</bean>
也可以将proxy-target-class设置为false,从而要求它生成基于接口的代理:
<bean id="jDShoppingCart" class="soundSystem.JDShoppingCart" scope="session">
<aop:scoped-proxy proxy-target-class="false"/>
</bean>
Spring-bean的作用域的更多相关文章
- Spring Bean的作用域(转)
Spring Bean的作用域 .singleton [单例] eg:<bean id="personService" class="com.yinger.ser ...
- Spring bean的作用域以及生命周期
一.request与session的区别 request简介 request范围较小一些,只是一个请求. request对象的生命周期是针对一个客户端(说确切点就是一个浏览器应用程序)的一次请求,当请 ...
- spring bean 的作用域之间有什么区别
spring bean 的作用域之间有什么区别? spring容器中的bean可以分为五个范围.所有范围的名称都是说明的, 1.singleton:这种bean范围是默认的,这种范围确保不管接受到多个 ...
- spring bean 的作用域
spring bean 的作用域: 1.单例(singleton):默认是单例模式,也就是说不管给定的bean被注入到其他bean多少次,注入的都是同一个实例. 2.原型(prototype):每次注 ...
- Spring bean的作用域和生命周期
bean的作用域 1.singleton,prototype, web环境下:request,session,gloab session 2.通过scope="" 来进行配置 3. ...
- [跟我学spring][Bean的作用域]
Bean的作用域 什么是作用域呢?即“scope”,在面向对象程序设计中一般指对象或变量之间的可见范围.而在Spring容器中是指其创建的Bean对象相对于其他Bean对象的请求可见范围. Sprin ...
- Spring Bean的作用域类型
Bean的作用域类型 singleton :在Spring IOC容器中仅存在一个Bean实例,Bean以单实例的方式存在; prototype :每次从容器中调用Bean时,都返回一个新的实例,即每 ...
- spring bean的作用域和自动装配
1 Bean的作用域 l singleton单列:整个容器中只有一个对象实例,每次去访问都是访问同一个对象 默认是单列 l prototype原型: 每次获取bean都产生一个新的对象,比如Ac ...
- Spring Bean Scope (作用域)
singleton: 单例模式,针对每个spring容器,只有一个该类的实例被管理,每次调用此实例都是同一个对象被返回,所以适用于无状态bean.默认情况下,singleton作为spring容器中b ...
- Spring Bean的作用域以及lookup-method标签的使用
Spring Framework支持五种作用域,如下图所示: singleton:表示一个容器中只会存在一个bean实例,无论在多少个其他bean里面依赖singleton bean,整个容器都只会存 ...
随机推荐
- WIN2008中部署网站后样式及JS加载不了
今天在一台刚刚装好的WIN2008上部署一个问题,一切按流程来:① 控制面板加IIS,把.NET 3.5打勾② 装.NET 4.0框架③ 装MSSQL2012④ IIS中部署网站⑤ 修改web.con ...
- [svc][op]LVS+keepalived
lvs是一种负载均衡技术.注意区分负载均衡和高可用的区别. keepalive是lvs的管理工具 ipvsadm也是lvs的管理工具 keepalive借助ipvsadm管理lvs.所以通常说lvs+ ...
- dp之区间:最大k乘积
题目:给你一个n(1<=n<=15)位数,求将它分成m段,用m-1个*连接起来的最大乘积....... 思路:定义dp[i][j]为将前i位数分成j段的最大乘积,那么dp[i][j]==m ...
- JavaScript高级 面向对象(7)--深拷贝与浅拷贝
说明(2017.3.31): 1. 画图: var car = {name:"法拉利"}; var p = {name: "张三", age: "19 ...
- iphone 6plus 下app里的状态栏和界面会被放大的问题//以及设置APP闪屏页/APP图标流程
//设置APP闪屏页/APP图标流程如下 2.6Plus界面显示变大以及APP图标变大是由于上面图片的AppIcon以及LaunchImage造成的,主要是由于找不到对应的3x图片,或者改3x图片尺寸 ...
- 一款纯css实现的漂亮导航
今天给大家分享一款纯css实现的漂亮导航.之前为大家分享过jquery实现的个人中心导航菜单,今天这款也是适合放在个人中心.还带来图标,效果不错.一起看下效果图: 在线预览 源码下载 实现的代码. ...
- if的另一个实现思路
在一些场景中需要根据根据一个传入的额值来做不同的处理,而且if有很多层,此时如果一直写if代码就会雍容.一种比较好的方法就是写一个map列出与if对应的情况,然后map的value就能放一些方法或者其 ...
- 简易web项目jdbcUtil
jdbc.username=root jdbc.password=root jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://mini1: ...
- MySQL 时间戳(Timestamp)函数
1. MySQL 获得当前时间戳函数:current_timestamp, current_timestamp() mysql> select current_timestamp, curren ...
- kubernetes健康检查
有时候容器在running的状态,但是里面的服务挂了,这个就难办了,所以k8s提供了一种检查服务是否健康的方法 Liveness Probe的种类: ● ExecAction:在container中执 ...