4.3 KiB
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级别。