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 Bean的作用域决定了Bean的生存周期,Spring支持多种作用域,如singleton、prototype等。Singleton作用域下,整个容器期间只有一个Bean实例;Prototype作用域下,每次请求都会创建一个新的...
Spring.Bean.Scopes.Example-master这个压缩包很可能是包含了一个Spring Boot项目,该项目内有示例代码,演示了如何配置和使用这两种Bean Scope。项目中可能包括以下部分: - 配置类(Configuration Classes):...
4. **Bean的作用域(Scopes)** - Spring提供了多种Bean的作用域,包括单例(Singleton)、原型(Prototype)、请求(Request)、会话(Session)和全局会话(Global Session)。这些作用域决定了Bean的实例化策略...
2. **bean的作用域(Bean Scopes)** - **2.1 Singleton**:每个bean定义只有一个实例,全局共享。 - **2.2 Prototype**:每个请求(或配置)都会创建一个新的bean实例。 - **2.3 Request**:在Web应用中,每个...
- **New bean scopes**: 添加了新的作用域类型,如`request`、`session`等,用于更好地管理和控制Bean的生命周期。 - **Extensible XML authoring**: 允许用户通过自定义命名空间扩展Spring的配置文件结构,提供了更...
- 介绍了自动装配机制,即如何让Spring自动找到合适的bean并注入到其他bean中。 - **3.4.6 Method injection** - 如何通过方法参数进行依赖注入。 - **3.5 Bean作用域** - **3.5.1 单例作用域** - 单例bean在...
- **Beans scopes**:解释了不同作用域下的Bean实例化行为。 - **Customizing the nature of a bean**:讲述了如何定制Bean的行为,如初始化、销毁方法等。 - **Bean definition inheritance**:说明了如何通过继承...
- 新的Bean作用域(New bean scopes) Spring 2.5引入了更多的Bean作用域,如prototype(原型)和session,使得开发者可以更灵活地控制Bean的生命周期。 - 更简单的XML配置(Easier XML configuration) 2.5版本...
- **The Beans**:Bean是Spring框架中的基本单位,每一个Bean都有一个唯一的名称,并且可以在配置文件中定义其初始化参数、依赖关系等。 - **Using the Container**:一旦容器被实例化,就可以通过它来获取所需的...
3. **Bean Scopes**: Spring定义了多种Bean的作用域,包括Singleton(单例)、Prototype(原型)、Request、Session、Global Session等。Singleton Bean在整个容器生命周期内只有一个实例,而Prototype Bean每次...
- **New bean scopes**:引入了新的bean作用域,如`request`和`session`等,这些作用域特别适用于Web应用中的特定场景。 - **Extensible XML authoring**:通过提供更多的自定义选项,Spring 2.0使得XML配置更加灵活...
在 Spring 中,singleton scope 是默认的 scopes,表示 Bean 只会被实例化一次,并且可以被所有的应用程序上下文访问。 2.Factory Pattern:工厂模式,提供一种创建对象的方式,封装创建对象的细节。 在 Spring 中...
动作实现可以采用多种方式,如Java类、Groovy脚本、Spring Bean等。Spring Web Flow的灵活性使得开发者可以根据具体需求选择最适合的动作实现方式。 #### 6.6 Action exceptions 动作执行过程中可能会抛出异常,...
然后是**豆范围(Bean Scopes)**,Spring支持多种Bean的作用域,包括单例(Singleton)、原型(Prototype)、请求(Request)、会话(Session)等。理解不同作用域的含义和使用场景是确保应用程序正确运行的关键。...
Aliasing a bean outside the bean definition ................................................ 28 Instantiating beans .......................................................................................
Aliasing a bean outside the bean definition ................................................ 28 Instantiating beans .......................................................................................
clients.inMemory().withClient("client").secret("secret").authorizedGrantTypes("authorization_code", "refresh_token").scopes("read", "write"); } } ``` TokenStore TokenStore 负责存储 access_token。...