八、Bean的作用范围

来源:互联网 发布:数据统计与分析专业 编辑:程序博客网 时间:2024/06/08 06:32

Bean可以定义为部署在多个范围之一中:开箱即用,Spring Framework支持七个范围,其中五个范围仅在使用Web感知时可用ApplicationContext。

Bean范围

范围 描述 singleton Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例 prototype prototype作用域部署的bean,每一次请求(将其注入到另一个bean中,或者以程序的方式调用容器的 getBean()方法)都会产生一个新的bean实例,相当与一个new的操作,对于prototype作用域的bean,有一点非常重要,那就是Spring不能对一个prototype bean的整个生命周期负责,容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法,而对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。 清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。 request 为每个 HTTP 请求创建它自有的一个 Bean 实例,仅在 Web 相关的 ApplicationContext 中生效。 session 为每个 HTTP 会话创建一个实例,仅在 Web 相关的 ApplicationContext 中生效。 global session 为每个全局的 HTTP 会话创建一个实例。一般仅在 porlet 上下文中使用生效。同时仅在 Web 相关的 ApplicationContext 中生效 application 为每个 ServletContext 创建一个实例。仅在 Web 相关的 ApplicationContext 中生效。 websocket 将单个bean定义范围到a的生命周期WebSocket。只有在Web感知Spring的上下文中才有效ApplicationContex

singleton

只管理一个单例bean的一个共享实例,并且对于具有与该bean定义匹配的id或id的bean的所有请求都会导致Spring容器返回一个特定的bean实例。

换句话说,当您定义一个bean定义并将其定义为单例时,Spring IoC容器将仅创建由该bean定义定义的对象的一个实例。该单个实例存储在这样的单例bean的缓存中,并且该命名bean的所有后续请求和引用返回缓存的对象。

<bean  id = “accountServiceclass = “com.foo.DefaultAccountService” />< - 以下是等效的,尽管是冗余(单例范围是默认值) - > <bean  id = “accountServiceclass = “com.foo.DefaultAccountServicescope = “singleton” />

prototype

bean的部署的非单例,原型范围导致在每次对该特定bean进行请求时创建一个新的bean实例。也就是说,bean被注入到另一个bean中,或者通过getBean()容器上的方法调用来请求它。通常,对于无状态bean,可以使用所有有状态bean的原型范围和单例范围

<bean  id = “accountServiceclass = “com.foo.DefaultAccountServicescope = “prototype” />

request

request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效.
request、session、global session使用的时候首先要在初始化web的web.xml中做如下配置:
如果你使用的是Servlet 2.4及以上的web容器,那么你仅需要在web应用的XML声明文件web.xml中增加下述ContextListener即可:

<web-app>   ...  <listener><listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>  </listener>   ...</web-app>

如果是Servlet2.4以前的web容器,那么你要使用一个javax.servlet.Filter的实现:

<web-app> .. <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>   ...</web-app>

作用域 Bean 依赖

如果想把一个 HTTP request 作用域的 Bean 注入到另一个长周期作用域的 Bean 中,就需要选择注入一个 AOP 代理来替换这个 request 作用域 Bean 。也就是,需要注入一个代理对象,这个代理对象暴露了 request 作用域 Bean 的公共接口,可以查找到真实的目标对象,然后将方法调用委托到真实的对象上面。比如在单例 Bean 中注入一个会话 Bean ,若不使用代理,那么在会话 Bean 失效之后,单例 Bean 将不能再获取到会话 Bean 。若使用代理,那么代理对象将从作用域机制中找到对应的 Bean 。

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:aop="http://www.springframework.org/schema/aop"    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/aop        http://www.springframework.org/schema/aop/spring-aop.xsd">    <!—一个HTTP 会话作用域的Bean 作为代理暴露出去-->    <bean id="userPreferences" class="com.foo.UserPreferences" scope="session">        <!—指示容器代理这个Bean -->        <aop:scoped-proxy/>    </bean>    <!—一个单例Bean注入一个代理Bean -->    <bean id="userService" class="com.foo.SimpleUserService">        <!-- a reference to the proxied userPreferences bean -->        <property name="userPreferences" ref="userPreferences"/>    </bean></beans>

请求范围

当使用注释驱动的组件或
Java Config时,@RequestScope可以使用注释将组件分配给request作用域。

@RequestScope @Component public  class LoginAction {     // ... }
0 0
原创粉丝点击