spring的bean的scope主要是用来指定如何创建bean对象的,系统已经实现的主要有五中类型,分别是:singleton、prototype、request、session和globalSession,其中request、session和globalSession是只能在web环境中使用的 ,当你在非web环境中使用它们时,系统会抛出IllegalStateException异常,
当然这个也是可以自己进行定义的。
注意:在使用request、session和globalSession的时候,如果你用的不是springMVC的话是需要做一点配置的,具体做法是:
a、如果你用的是servlet2.4+的话,那么你需要在web.xml中加入一个RequestContextListener监听器
<web-app> ... <listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class> </listener> ... </web-app>
b、当然,如果你用的是再老一点的版本的话,你需要在web.xml中加入一个RequestContextFilter
<filter> <filter-name>requestContextFilter</filter-name> <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class> </filter> <filter-mapping> <filter-name>requestContextFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
基于xml方式的scope指定:
<bean id="test" class="com.xxx.spring.cope.Test" scope="singleton"/>
1.singleton,系统默认的scope就是singleton,它表示在整个请求过程中都只会创建一个bean对象,该对象创建以后是保存在singleton beans的缓存中的,以后每次需要的时候都会去取得同一个bean对象。
值得注意的是spring里面的singleton(单例)跟GOF设计模式里面的单例是有区别的,GOF里面的单例是每个类加载器下面只会有一个对象,而spring里面的singleton是每个spring容器会拥有一个对象。
2.prototype:
prototype不是单例形式的,它会在每次有一个新的请求来请求当前对象的时候都会生成一个新的对象。
值得注意的是当一个singleton的bean A 依赖于一个prototype的bean B 的时候,由于singleton的bean A 只会初始化一次,那么如果在其初始化的时候就给其注入一个prototype的bean B 的时候,A拥有的B就只会在A初始化的时候初始化一次,而且每次在A使用B的时候都是用的同一个对象B,这与我们原始想的B为prototype有点违背,不是我们想要的结果,其解决办法是,使bean A 实现一个ApplicationContextAware接口,在每次A需要使用B的时候都从ApplicationContext里面取一个B对象,这个时候取的B对象每次都会是不一样的。
import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class A implements ApplicationContextAware { private ApplicationContext applicationContext; private B b; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // TODO Auto-generated method stub this.applicationContext = applicationContext; } public B getB() { return applicationContext.getBean(B.class); } public void setB(B b) { this.b = b; } }
import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component @Scope("prototype") public class B { //类里面的其他内容 }
3、request:
先看下面这样一个bean定义:
<bean id="loginAction" class="com.xxx.LoginAction" scope="request"/>
上面的情况,在每次有一个http Request请求LoginAction的时候,spring容器都会新建一个全新的LoginAction对象。这就是Request级别的scope。由于每个请求都对应一个全新的LoginAction对象,所以在请求过程中,你可以随意改变其中包含的实例属性。当一次Request请求完毕之后,其对应的LoginAction对象也就被销毁了。
4、session:
先看下面这样一个bean定义:
<bean id="UserService" class="com.xxx.UserService" scope="session"/>
在上面这种情况,spring容器会为每个处于活跃状态的http Session创建一个UserService对象,这就是session级别的scope。其是和httpSession一起销毁的。
5.globalSession:
先看下面这样一个bean定义:
<bean id="UserService" class="com.xxx.UserService" scope="globalSession"/>
globalSession表示在一个全局的HttpSession下会拥有一个单独的实例,通常用于Portlet环境下。
当需要把一个http级别的scope的对象注入到其他bean中的时候,需要在声明的http级别的scope的对象中加入<aop:scoped-proxy/>,如下面的userPreferences对象
<!-- an HTTP Session-scoped bean exposed as a proxy --> <bean id="userPreferences" class="com.foo.UserPreferences" scope="session"> <!-- this next element effects the proxying of the surrounding bean --> <aop:scoped-proxy/> </bean> <!-- a singleton-scoped bean injected with a proxy to the above bean --> <bean id="userService" class="com.foo.SimpleUserService"> <!-- a reference to the proxied userPreferences bean --> <property name="userPreferences" ref="userPreferences"/> </bean>
这样做的原因 是正常情况下singleton的userService中有一个session级别的对象,这样singleton的userService只初始化一次,而其所依赖的session级别的userPreferences也只初始化一次。这就与我们所定义的每个session对应一个对象的初衷相违背了,而使用<aop:scoped-proxy/>的时候,就会在实际调用的时候每次使用代理去代理userPreferences调用其对应的方法,代理访问的是对应的session中的对象,这样就可以实现每个session对应一个对象。而在代理的时候有两种方式,一种是基于JDK的interface的,一种是CGLIB形式的,如果要代理的类是面向对象的,就可以直接使用JDK的代理,否则就需要开启对CGLIB代理的支持,同时要引入CGLIB的jar包。
<bean id="userPreferences" class="com.foo.DefaultUserPreferences" scope="session"> <aop:scoped-proxy proxy-target-class="false"/><!-- 为true则为开启对CGLIB的支持 --> </bean>
相关推荐
NULL 博文链接:https://moshow.iteye.com/blog/1607598
自定义 Spring Bean Scopes 用于默认设置不起作用的情况 可用范围 Route Scope - 提供每个路由执行范围的范围 页面范围 - 提供每页范围的范围 线程范围 - 提供每个线程范围的范围 继承的线程范围 - 提供每个线程...
Spring.Bean.Scopes.Example 这是一个示例,向您展示 bean 范围之间的区别:单例和原型。
Laravel开发-laravel-scopes .zip
Laravel开发-laravel-scopes Laravel的查询生成器的方便范围。
Laravel开发-eloquent-scopes 雄辩(laravel)查询生成器的方便范围。
Laravel开发-laravel-eloquent-scopes 雄辩的一般范围
Aliasing a bean outside the bean definition ................................................ 28 Instantiating beans .......................................................................................
Desigo CC手册-08_Scopes_BA_CN(审视)
Spring Boot集成Spring security OAuth2事例 oauth:认证服务器、资源服务器 client-1:资源服务器,与oauth实现SSO client-2:资源服务器,使用RemoteTokenServices进行token验证(无法同时使用SSO和OAuth来保护...
MATLAB课件:ch4_functions_and_scopes.pdf
Aliasing a bean outside the bean definition ................................................ 28 Instantiating beans .......................................................................................
scopes.js是该库的主要模块版本:1.1.0先决条件符合ECAScript 2015的Javascript环境安装NPM软件包-`npm install prop-scopes'测验存储库包含脚本testbed.js ,该脚本包含用于测试范围库功能的可选功能列表。...
github-oauth-scopes 用于处理github宣誓范围的实用程序 var ghScopes = require ( 'github-oath-scopes' ) ; ghScopes . isValid ( 'repo' ) ; // true ghScopes . isValid ( 'bad_scope' ) ; // false ghScopes ...
另外,项目“ Understanding Scopes”展示了JSF范围之间的差异(包括更奇特的sopes,例如@CustomScope或@NoneScope)。 他们还研究了在JSF类中使用Spring类的几种方法(另请参见我的文章 )。 重要的提示: 如果...
资源分类:Python库 所属语言:Python 资源全名:px-access-scopes-0.1.2.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
In Pro CDI 2 in Java EE 8, use CDI and the CDI 2.0 to automatically manage the life cycle of your enterprise Java, Java EE, or Jakarta EE application’s beans using predefined scopes and define custom...
范围是一种使用Java EE Web应用程序范围的新方法,它提供了表示所有Web上下文的独立于Web平台的状态对象,并提供了可扩展的框架来创建除“请求”,“会话”和“应用程序”之外的新范围
ecma-scopes 的块和词法作用域名称列表我们使用的是由输出令牌 ,一个叉与ES6支持。 创建它是为了使检测范围边界更容易并经过良好测试。 它是项目的一部分,这是一个插件,有助于将混淆变量重命名为更易识别的变量。...