54 lines
4.3 KiB
Markdown
54 lines
4.3 KiB
Markdown
# Spring IOC
|
||
## Bean Scope
|
||
### 简介
|
||
当创建一个bean定义时,实际上根据bean定义创建了一个配方,该配方用于创建类型的实际实例。可以基于一个配方创建多个对象实例。
|
||
|
||
### singleton
|
||
对于一个被容器管理的singleton bean来说,只在容器中存在一个共享的实例。所有针对该bean的请求,spring容器都会返回同一个实例。
|
||
|
||
当创建一个singleton bean定义时,spring容器会为该bean定义创建一个实例,该单实例会存储在cache中,该cache专门用于存储类似的单实例对象。所有针对单实例对象的请求都会返回该cache中的对象。
|
||
|
||
singleton scope并不代表针对特定类型只创建一个实例对象。singleton scope代表在同一个容器中,只会存在一个该类型的bean对象。
|
||
|
||
### Prototype Scope
|
||
对于prototype scope的bean对象,每次请求该bean对象时,都会创建一个新的bean实例。
|
||
|
||
故而,应该对拥有状态(stateful)的bean对象使用prototype scope,而对无状态(stateless)的bean而对象使用singleton scope。
|
||
|
||
和其他scope bean不同,spring容器并不管理prototype bean的完整生命周期。容器会实例化、配置、组装prototype对象,并将其传递给调用方,之后spring便不再记录prototype bean对象。
|
||
|
||
初始化生命周期的回调方法将会针对所有scope的bean对象调用,但是对于prototype bean,销毁生命周期的回调接口并不会被调用。用户在获取prototype bean之后,必须对自己对prototype bean对象的内容进行清除,并且释放bean对象中持有的资源。
|
||
|
||
### singleton bean中的prototype bean依赖
|
||
如果一个singleton bean中含有prototype bean依赖,singleton bean中的依赖是在实例化时解析的。实例化时创建的prototype bean实例是singleton bean所应用的prototype bean的唯一实例。(**代表singleton bean引用的prototype bean有且仅有一个实例**)。
|
||
|
||
如果想要在singleton bean运行时不断的获取新的prototype bean实例,不能简单将prototype bean作为依赖注入到singleton bean中,因为依赖注入只能在singleton bean初始化时获取prototype bean一次。可以在运行时通过getBean方法不断获取prototype bean实例,每次获取的实例都是一个新的实例。
|
||
|
||
### request, session, application, websocket scopes
|
||
`request`、`session`、`application`、`websocket` scope都只在web环境下可用,需要使用web-aware的ApplicationContext实现(例如XmlWebApplicationContext)。如果在常规spring ioc容器中使用上述scope,会抛出IllegalStateException 异常。
|
||
|
||
### request scope
|
||
对于request scope,针对每个http请求都会创建一个新的bean实例。request scope bean的作用域范围在http request级别,可以在请求处理的过程中任意修改bean对象的状态,因为在其他请求中也有该request scope bean,一个请求对bean对象的修改对其他请求不可见。
|
||
|
||
当http请求完成后,该请求关联的request scope bean将会被丢弃。
|
||
|
||
注解`@RequestScope`可以在bean定义上进行标注,代表该bean对象为request scope
|
||
|
||
> #### request scope
|
||
> spring mvc中,请求和线程相绑定,如果在接收到一个请求后,在新的线程中对请求进行处理,那么新的线程将不会绑定旧的http请求。
|
||
>
|
||
> 对于request scope,只有在接收请求的线程内,调用getBean方法才能获取到bean实例,若新开一个线程处理请求,那么在新线程内调用getBean方法将会抛出异常
|
||
|
||
### Session Scope
|
||
对于一个http session,spring容器会针对session scope bean创建一个bean实例,该实例在session范围内有效。session范围内可以任意修改bean实例的状态,一个session内对bean的修改对其他session是不可见的。
|
||
|
||
当session会话结束时,与该http session关联的bean对象也会被丢弃。
|
||
|
||
注解`@SessionScope`可以将bean对象定义为session scope。
|
||
|
||
### application scope
|
||
针对一个web application,spring容器会创建一个bean对象实例。在这种情况下,application scope bean将会范围将会被限定为ServletContext级别,并且bean实例会作为`ServletContext`的属性被存储。
|
||
|
||
注解`@ApplicationScope`可以将bean对象的范围限定为`serveltContext`级别。
|
||
|