我们知道,Spring容器中的bean对象有不同的作用域,对于一个Web应用中,常见的作用域有:singleton,prototype,request,session,application。对于一个bean定义,如果没有特殊指定,其缺省的作用域为singleton。
比如我们通过注解@Service,@Controller,@Component,@Repository所定义的组件bean,缺省都是singleton作用域。
对于以上这些作用域,它们的具体含义如下:
| 作用域 | 含义描述 |
|---|---|
singleton | 整个Spring IoC容器内只有一个这样的bean,生成后一直保持到容器销毁 |
application | 整个ServletContext视为一个应用,在这个应用内只有一个这样的bean,创建之后一直保持到该ServletContext销毁 |
session | 整个HTTP Session对应只有一个这样的bean,创建之后一直保持到该HTTP session被销毁 |
request | 整个HTTP request请求处理过程对应只有一个这样的bean,创建之后一直保持到该HTTP request处理完被销毁 |
prototype | 每次从容器获取该bean都会得到一个新的实例,会被如何保持,会被保持多长时间,都由使用者决定,容器不再管理 |
对于上面的这些作用域,singleton/prototype使用于任何类型的Spring应用,而application/session/request仅仅针对Spring Web应用。
另外从这些作用域的长短或者说对应bean的可见性上来看,可以这么排序 :
singleton>application>request>session
这里 prototype并没有被放到排序里面,原因是容器只负责这类bean的创建,而至于这类bean会被如何保持,保持多长时间,都由使用者自行决定,所以这里的排序没有考虑它。
根据上面这些作用域的定义,不难理解,将一个较大作用域的bean注入到一个较小作用域的bean中是可行的。但是,是否可以将一个较小作用域的bean注入到一个较大作用域的bean中呢?仅仅从概念上理解,似乎是行不通的。但结合各种实现技术,Spring做到了这一点。简单点讲,Spring典型的做法是,当要将以一个小作用域的bean注入到一个大作用域的bean中时,Spring注入的其实是一个代理对象,可以理解该代理对象的作用域级别一定不小于注入目标bean的作用域,并且该代理对象会在使用者想获取小作用域的bean时,动态地分析当前的运行时上下文,获取该小作用域bean给使用者。典型的一个例子,可以参考在singleton Web控制器bean组件中注入request级别作用域HttpServletRequest bean的例子。
本文详细阐述了Spring容器中bean的不同作用域,包括singleton、prototype、request、session和application,探讨了它们之间的注入可能性及Spring如何处理不同作用域bean的注入问题。

被折叠的 条评论
为什么被折叠?



