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容器(BeanFactory和ApplicationContext)会拥有一个对象。
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
- **3.5 Bean作用域** - **3.5.1 单例作用域** - 单例bean在整个Spring IoC容器中只有一个实例。 - **3.5.2 The prototype作用域** - 每次请求时都会创建一个新的bean实例。 - **3.5.3 Singleton beans with ...
- **New bean scopes**: 添加了新的作用域类型,如`request`、`session`等,用于更好地管理和控制Bean的生命周期。 - **Extensible XML authoring**: 允许用户通过自定义命名空间扩展Spring的配置文件结构,提供了更...
在实践中,可以根据需求选择合适的注入方式、bean作用域和依赖检查策略,以优化系统的性能和可扩展性。随着经验的积累,你还可以探索更高级的特性,如Spring Boot、Spring Data和Spring Cloud等,进一步提升开发效率...
- **New Bean Scopes**:引入了新的Bean作用域,如singleton、prototype等,以满足不同场景的需求。 - **Extensible XML Authoring**:支持自定义扩展XML配置,进一步提高了灵活性。 ##### 2.2 Aspect-Oriented ...
4. **Bean的作用域(Scopes)** - Spring提供了多种Bean的作用域,包括单例(Singleton)、原型(Prototype)、请求(Request)、会话(Session)和全局会话(Global Session)。这些作用域决定了Bean的实例化策略...
- 新的Bean作用域(New bean scopes) Spring 2.5引入了更多的Bean作用域,如prototype(原型)和session,使得开发者可以更灵活地控制Bean的生命周期。 - 更简单的XML配置(Easier XML configuration) 2.5版本...
在Spring框架中,Bean的Scope是管理对象生命周期和作用域的关键概念。Bean的Scope定义了在应用程序上下文中如何创建和管理Bean的实例。本示例着重于两种主要的Bean Scope:单例(Singleton)和原型(Prototype),并...
- **Beans scopes**:解释了不同作用域下的Bean实例化行为。 - **Customizing the nature of a bean**:讲述了如何定制Bean的行为,如初始化、销毁方法等。 - **Bean definition inheritance**:说明了如何通过继承...
Bean定义描述了Bean的元数据,包括Bean的类、作用域、初始化方法等,是Spring IoC容器管理Bean的基础。 #### Spring Bean Scopes Bean的作用域决定了Bean的生存周期,Spring支持多种作用域,如singleton、...
- **New bean scopes**:引入了新的bean作用域,如`request`和`session`等,这些作用域特别适用于Web应用中的特定场景。 - **Extensible XML authoring**:通过提供更多的自定义选项,Spring 2.0使得XML配置更加灵活...
Spring定义了多种Bean的作用域,包括Singleton(单例)、Prototype(原型)、Request、Session、Global Session等。Singleton Bean在整个容器生命周期内只有一个实例,而Prototype Bean每次请求都会创建一个新的...
Spring Web Flow采用了一种层次化的范围搜索算法,当访问一个EL变量时,它会按照预定义的顺序在不同的作用域中查找该变量,确保了数据访问的正确性和高效性。 ### 五、Rendering views #### 5.1 Introduction 视图...
然后是**豆范围(Bean Scopes)**,Spring支持多种Bean的作用域,包括单例(Singleton)、原型(Prototype)、请求(Request)、会话(Session)等。理解不同作用域的含义和使用场景是确保应用程序正确运行的关键。...