目录
3. request、session、application、websocket作用域
关注 “JAVA学习课堂” 微信公众号,获取更多学习笔记,。
在Spring
中,那些组成应用程序的主体由Spring IoC
容器所管理的对象,被称之为bean
。简单地讲,bean
就是由IoC
容器初始化、装配及管理的对象。
在Spring Framework
中,总共定义了6种bean
的作用域,其中有4种作用域只有当应用为web
应用的时候才有效,并且Spring
还支持自定义作用域。
1、singleton(单例模式)
如果一个bean的
作用域为Singleton
,那么Spring IoC
容器中只会存在一个共享的bean
实例。当获取bean
时,只要id
与该bean
相匹配,就会返回同一bean
的实例。Singleton
是单例模式,就是在创建容器时就同时自动创建了一个bean
的对象,不管你是否使用,它都已经存在了,且每次获取到的对象都是同一个对象。
注:上图中,有3个地方引用了这个bean,这3个引用指向的都是同一个bean实例。
singleton
作用域是Spring中默认的作用域,可以在定义bean
的时候指定或者不指定都可以,如下:
<!-- 不指定作用域,默认是singleton -->
<bean id="accountService" class="com.something.DefaultAccountService"/>
<!-- 显示指定作用域为singleton -->
<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>
测试:
<bean id="user" class="com.atangbiji.pojo.User" scope="singleton">
<property name="name" value="zcm"/>
<property name="age" value="18"/>
</bean>
import com.atangbiji.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void testDI3(){
//userBeans.xml文件,IOC容器生成并管理相应的Bean对象
ApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml");
//通过Spring的上下文对象,从IOC容器中获取Bean对象
User user1 = (User)context.getBean("user");
User user2 = (User)context.getBean("user");
//输出两个对象的HashCode,并判断两个对象是否相同
System.out.println(user1.hashCode());
System.out.println(user2.hashCode());
System.out.println(user1 == user2);
}
}
执行结果如下图所示:
可以发现:两次代码执行的hashCode
地址是相同的,可以证明,Spring IoC
容器中只会存在一个共享的bean
实例
2、prototype(原型模式)
prototype
作用域表示的是一个bean
定义可以创建多个bean
实例,有点像一个类可以new
多个实例一样。
也就是说,当注入到其他的bean
中或者对这个bean
定义调用getBean()
时,都会生成一个新的bean
实例。
prototype
作用域表示的是一个bean
定义可以创建多个bean
实例,有点像一个类可以new
多个实例一样。
也就是说,当注入到其他的bean
中或者对这个bean
定义调用getBean()
时,都会生成一个新的bean
实例。
prototype
作用域的工作过程如图:
Prototype
是原型模式,它在我们创建容器的时候并没有实例化,而是当我们获取bean
的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。在XML
中将bean
定义成prototype
,可以这样配置:
测试:
<bean id="user" class="com.atangbiji.pojo.User" scope="singleton">
<property name="name" value="zcm"/>
<property name="age" value="18"/>
</bean>
重新运行测试代码后结果:
注:对有状态的bean
应该使用prototype
作用域;而对无状态的bean
则应该使用singleton
作用域。
3. request、session、application、websocket作用域
request
、session
、application
、websocket
作用域只有在web
环境下才有用。
3.1初始化web配置
为了支持request
、session
、application
、websocket
作用域,在定义bean
之前需要一些初始化配置。
如果你在Spring Web MVC
中定义这4中作用域,不需要进行初始化配置,如果你使用的是Servlet 2.5
web容器,这些容器不使用Spring
的DispatcherServlet
,你需要注册org.springframework.web.context.request.RequestContextListener
。对于Servlet 3.0+
的web容器,可以通过编程的方式使用WebApplicationInitializer
接口来完成,或者使用x
ml
配置:
<web-app>
...
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
...
</web-app>
3.2 request作用域
下面的xml
配置指定了bean
的作用域为request
:
<bean id="loginAction" class="com.something.LoginAction" scope="request"/>
3.3 session作用域
在xml
中可以这样定义bean
的作用域为session
作用域:
<bean id="userPreferences" class="com.something.UserPreferences" scope="session"/>
Spring
为每个HTTP Session
创建一个新的UserPreferences
的bean
。每个bean
之间是不可见的,只属于对应的Session
,当Session
销毁的时候,对应的bean
也会被销毁
3.4 application作用域
在xml
中可以这样定义bean
的作用域为application
作用域:
<bean id="appPreferences" class="com.something.AppPreferences" scope="application"/>
Spring
为整个web
上下文创建一个AppPreferences
的bean
。也就是说,这个bean
作用域是在ServletContext
级别,它是作为ServletContext
的一个属性存在的。
关注 “JAVA学习课堂” 微信公众号,获取更多学习笔记,。