一、bean scope范围
默认情况下spring中所有的bean都是单例的,即bean实例只有一个,我们可以在bean中添加scope属性来修改这个默认值。scope属性可用值如下:
singleton:每个spring容器有一个实例(默认值)。
prototype:允许bean可以被多次实例化,即用一次就创建一次。
request:定义bean的scope是HTTP请求,每个HTTP请求都有自己的实例,只有在使用有WEB功能的spring上下文时才有效。
session:定义bean的scope是HTTP会话,只有在使用有WEB功能的spring上下文时才有效。
application:每个ServletContext有一个实例。
websocket:每个WebSocket有一个实例,只有在使用有WEB功能的spring上下文时才有效。
二、singleton与prototype scope
singleton bean:是默认的创建bean方式,IoC容器只管理一个singleton bean的共享实例,所有对id或id匹配该bean定义的bean请求都会导致spring容器返回一个特定的bean实例。即当定义一个bean并将其定义为singleton时,IoC容器将会创建一个由该bean定义的对象实例,该单个实例存储在缓存中,对该bean所有后续请求和引用都将返回缓存中的对象实例。
prototype bean:IoC容器在每次对该特定bean请求时都会创建一个新的bean实例。类似于new操作。
一般情况下singleton可以适用于大部分场景,特殊情况下(如多线程)需要每次调用都生成一个新实例是就需要用prototype。
注意:不能依赖注入一个prototype范围的bean到singleton bean中,因为这个注入只发生一次,即当spring容器在实例化singleton bean并解析和注入它的依赖时。如果在运行时需要多次prototype bean的新实例,可以采用方法注入的方式。
三、request、session、application、websocket scope
request、session、application、websocket scope这几个scope都是只有在基于web的ApplicationContext实现中才能使用。在使用这几个scope,需要在配置bean之前做一些基础配置。如果使用了spring MVC框架,那么每个请求都会通过spring的DispatcherServlet或DispatcherPortlet来处理,就没有其他特殊的初始化配置。如果使用spring2.5,请求不是通过DispatcherServlet来处理,此时需要注册org.springframework.web.context.request.RequestContextListener或ServletRequestListener。在Servlet3.0之后,这些都可以通过WebApplicationInitializer接口来实现。如果是其他旧版本的容器,可以在web.xml中增加以下Listener声明:
<web-app>
...
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
...
</web-app>
或者使用spring的RequestContextFilter,Filter的映射取决于web应用的配置,如下模板配置,可根据情况修改:
<web-app>
...
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</filter>
...
</web-app>
DispatcherServlet、RequestContextListener、RequestContextFilter本质上一致,都是绑定请求对象到服务请求的线程上,使得bean在之后的调用链上可见。
四、自定义scope
用户可以定制自己的scope,实现org.springframework.beans.factory.config.Scope接口即可。
Scope接口定义自定义scope示例:
1、创建ThreadScope并实现Scope接口
2、修改spring.xml配置为自定义的scope
3、定义service接口及实现类
4、定义MessagePrinter
5、定义应用主类Application
运行结果--参考文献《Srping5开发大全》
网友评论