1前言
2基本原理
3IOC容器
4Bean
5依赖
6作用域
Bean的作用域是指bean的作用范围,用于指定 Bean的创建方式、Bean的生命周期,IOC容器根据Bean的配置元数据以及Bean的作用域对Bean执行实例化、执行依赖注入、执行实例的生命周期管理。Bean的作用域可以让开发者在不用修改代码的情况下,以更加灵活、更加高效、可配置的方式实行Bean对象实例的管理。Spring-Framework提供六种Bean作用域可配置的模式,如下所示:
singleton 界定Bean的作用域是单例模式,在IOC容器的生命周期内,创建一个唯一的(与ID标识对应)、共享的Bean对象实例,默认的创建方式 |
prototype 界定Bean的作用域是原型模式,在IOC容器的生命周期内,每一次请求、每一次依赖创建一个新的Bean对象实例 |
request 界定Bean的作用域是请求模式,在IOC容器的生命周期内,Bean的作用域与web应用上下文的保持一致(J2EE HTTP Request),每一次的web请求都创建一个Bean实例对象,在请求与响应的有效期内生效 |
session 界定Bean的作用域是会话模式,在IOC容器的生命周期内,Bean的作用域与web应用上下文的保持一致(J2EE HTTP Session),每一个的web会话创建一个Bean实例对象,在会话有效期内生效 |
application 界定Bean的作用域是应用模式,在IOC容器的生命周期内,Bean的作用域与web应用上下文的保持一致(J2EE HTTP ServletContext), 每一个的web应用创建一个Bean实例对象,在应用有效期内生效 |
websocket 界定Bean的作用域是web套字节模式,在IOC容器的生命周期内,Bean的作用域与web应用上下文的保持一致(J2EE HTTP WebSocket),每一次的web套接字连接创建一个Bean实例对象,在连接的有效期内有效 |
6.1单例模式
单例模式,是指在IOC容器的生命周期创建一个唯一(与ID标识对应)的Bean对象实例,其他Bean的依赖与引用都共享该单一的对象实例。单例模式常用于无状态的Bean对象实例。
在单例模式下,ID是accountDao的Bean对象实例在IOC容器的生命周期内是唯一的、共享的 |
scope等于singleton,表示ID等于accountService的Bean对象实例是单例模式 |
6.2原型模式
原型模式,是指在IOC容器的生命周期内,每一次的请求、每一次的依赖与引用都创建一个新(与ID标识对应)的Bean对象实例。原型模式常用于有状态的Bean对象实例,每个请求都可设定对应的状态,请求结束,则状态结束。
在原型模式下,ID是accountDao的Bean对象实例在IOC容器的生命周期内,每一次的请求、每一次的依赖都创建一个新的Bean对象实例 |
scope等于prototype,表示ID等于accountService的Bean对象实例是原型模式 |
6.3单例与原型
当单例模式的Bean对象实例依赖原型模式的Bean对象实例,IOC容器把原型模式的Bean对象实例当作单例模式的Bean对象实例进行处理。在实际的应用环境中,开发者可以使用方法级别的依赖注入处理这种每次请求都需要创建新的Bean对象实例的场景。
6.4Web模式
request、session、application、websocket作用域只在web应用中使用,例如,容器类型是XmlWebApplicationContext,如果在其他类型的容器中使用,则发生IllegalStateException类型的异常。
Web初始化
在J2EE运行环境中,Spring-Framewokr支持多种方式配置MVC,如下所示:
DispatcherServlet、RequestContextListener、 |
request模式
web应用中比较常用的使用场景是登录过程,每次登录业务流程中都创建一个请求作用域内的Bean实例对象,配置方式如下所示:
scope等于request,其对应J2EE HTTP request,表示ID等于loginAction的Bean对象实例是请求模式 |
在Java代码注解中使用RequestScope对应请求模式 |
会话模式
在web应用中,用户登录成功后,J2EE运行环境会生成会话信息,在会话有效期内,用户可进行一些常用的缓存操作,例如,用户级别的编好设置,如下所示:
scope等于session,其对应J2EE HTTP session,表示ID等于UserPreferences的Bean对象实例是会话模式 |
在Java代码注解中使用SessionScope对应会话模式 |
应用模式
在web应用中,通常存在一些在应用的生命周期内可共享的数据信息,任何类型的Bean对象实例都可以使用这些数据信息,例如应用级别的编好设置,如下所示:
scope等于application,其对应J2EE HTTP ServletContext,表示ID等于AppPreferences的Bean对象实例是应用模式 |
在Java代码注解中使用ApplicationScope对应应用模式 |
WebSocket模式
Websocket是http2协议提供的基于长连接的传输模式,其支持全双工通讯,在web运行环境中,常用于基于http协议的消息推送。(在后续章节中详细描述)
6.5代理模式
由于单例模式的Bean对象实例只支持依赖注入单例模式的Bean对象实例,因此,IOC容器提供代理模式,支持单例模式依赖注入原型模式的Bean对象实例,如下所示:
ID等于userPreferences的Bean对象实例使用标签aop:scoped-proxy,定义注入代理模式,如果类UserPreferences是接口,则IOC容器使用JDK提供的接口代理模式,如果类UserPreferences是实现类,则IOC容器使用GCLIB提供的实现类代理模式 |
ID等于userService的Bean对象实例是单例模式,其依赖于会话模式的userPreferences |
标签aop:scoped-proxy提供proxy-target-class属性支持设置接口代理、实现类代理,该属性等于false的时候,userPreferences需要实现一个或者多个接口 |
6.6定制模式
Spring-Framework提供接口支持作用域的扩展,开发者可以使用可扩展的作用域接口自定义作用域,自定义作用域可以覆盖已有的作用域、根据业务场景定义全新的作用域。
org.springframework.beans.factory.config.Scope 作用域定制化接口,根据实际的业务场景扩展并定义需要的作用域,其提供的可扩展方法如下所示: get方法 返回作用域内的对象实例 remove方法 删除作用域内的对象实例 registerDestructionCallback方法 注册执行回调的方法,在作用域对应的Bean对象实例被销毁的时候,执行该方法 getConversationId方法 返回作用域标识的ID |
registerScope方法 IOC容器提供的方法注册一个自定义的作用域Bean |
自定义一个SimpleThreadScope类型的作用域Bean,并将其注册到IOC容器中,名称是thread,在配置元数据中可直接引用与依赖 |
将自定义的作用域Bean注册到CustomScopeConfigurer中 |
在thing2中使用自定义的作用域thread |
(未完待续)