Bean scopes 作用域
5个:singleton,prototype,request,session,global session
singleton 是默认的作用域,容器只产生一个实例,只要调用的id相同,返回的实例就是同一个;
prototype 每次调用返回的是不同的实例;
Request, session, and global session scopes 这三个是WEB方面使用的,使用于基于web的Spring ApplicationContext实现(如XmlWebApplicationContext)
前二个
com.spring305.test.scope.po.SingletonScope.java
public class SingletonScope {
private int id = (int) (100 * Math.random());
public void printID() {
System.out.println(SingletonScope.class + " id=" + id);
}
}
com.spring305.test.scope.po.PrototypeScope.java
public class PrototypeScope {
private int id = (int) (100 * Math.random());
public void printID() {
System.out.println(PrototypeScope.class + " id=" + id);
}
}
src/testScope.xml
<bean id="singletonScope" class="com.spring305.test.scope.po.SingletonScope"></bean> <bean id="prototypeScope" class="com.spring305.test.scope.po.PrototypeScope" scope="prototype"></bean>
测试:
@Test
public void testSingletonProtoType(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("testScope.xml");
SingletonScope singletonScope1 = ctx.getBean("singletonScope",SingletonScope.class);
SingletonScope singletonScope2 = ctx.getBean("singletonScope",SingletonScope.class);
PrototypeScope prototypeScope1 = ctx.getBean("prototypeScope",PrototypeScope.class);
PrototypeScope prototypeScope2 = ctx.getBean("prototypeScope",PrototypeScope.class);
singletonScope1.printID();
singletonScope2.printID();
prototypeScope1.printID();
prototypeScope2.printID();
}
得到结果:
class com.spring305.test.scope.po.SingletonScope id=89
class com.spring305.test.scope.po.SingletonScope id=89
class com.spring305.test.scope.po.PrototypeScope id=12
class com.spring305.test.scope.po.PrototypeScope id=50
singleton的值没有变化,而prototype的变化
再看后三种:
web.xml中加入spring Listener
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<!-- classpath:applicationContext.xml -->
<param-value>/WEB-INF/testScope.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<servlet>
<servlet-name>ScopeTest</servlet-name>
<servlet-class>
com.spring305.test.scope.po.ScopeTest
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ScopeTest</servlet-name>
<url-pattern>/ScopeTest</url-pattern>
</servlet-mapping>
/WEB-INF/testScope.xml
<bean id="singletonScope" class="com.spring305.test.scope.po.SingletonScope"></bean> <bean id="prototypeScope" class="com.spring305.test.scope.po.PrototypeScope" scope="prototype"></bean> <bean id="requestScopeT" class="com.spring305.test.scope.po.RequestScope" scope="request"></bean> <bean id="sessionScopeT" class="com.spring305.test.scope.po.SessionScope" scope="session"></bean> <bean id="globalSessionScope" class="com.spring305.test.scope.po.GlobalSessionScope" scope="globalSession"></bean>
servlet doGet内容如下:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
System.out.println("in get");
ServletContext context = getServletContext();
ApplicationContext ctx = null;
if (ctx == null)
{
ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
}
/**
* SingletonScope singletonScope1 = ctx.getBean("singletonScope",SingletonScope.class);
SingletonScope singletonScope2 = ctx.getBean("singletonScope",SingletonScope.class);
PrototypeScope prototypeScope1 = ctx.getBean("prototypeScope",PrototypeScope.class);
PrototypeScope prototypeScope2 = ctx.getBean("prototypeScope",PrototypeScope.class);
singletonScope1.printID();
singletonScope2.printID();
prototypeScope1.printID();
prototypeScope2.printID();
*/
RequestScope requestScope = (RequestScope) ctx.getBean("requestScopeT");
requestScope.printID();
SessionScope sessionScope = (SessionScope) ctx.getBean("sessionScopeT");
sessionScope.printID();
GlobalSessionScope gScope = (GlobalSessionScope)ctx.getBean("globalSessionScope",GlobalSessionScope.class);
gScope.printID();
out.println("123");
out.flush();
out.close();
}
同一浏览器刷新二次得到结果:
in get
class com.spring305.test.scope.po.RequestScope id=11
class com.spring305.test.scope.po.SessionScope id=50
class com.spring305.test.scope.po.GlobalSessionScope id=70
in get
class com.spring305.test.scope.po.RequestScope id=92
class com.spring305.test.scope.po.SessionScope id=50
class com.spring305.test.scope.po.GlobalSessionScope id=70
可见,除了requet的值变化了,session,globalsession的都没有变
换个浏览器刷新下servlet
in get
class com.spring305.test.scope.po.RequestScope id=96
class com.spring305.test.scope.po.SessionScope id=89
class com.spring305.test.scope.po.GlobalSessionScope id=38
相对而言,值都变化了,那么globalsession为什么也会变?官方给出解释:
The global session scope is similar to the standard HTTP Session scope (described above), and
applies only in the context of portlet-based web applications
基于portlet的web应用中才有意义.
<!--EndFragment-->