Request scope and session scope are important web application concepts. Request scope is short-live scope, request scope object only exists in one HTTP request. But session scope is long-live than request scope, session scope object exists between every request in an HTTP session. Spring provides annotations for you to make a java bean exist in the request scope or session scope.
1. Spring @Scope Annotation.
- The @Scope annotation can define a spring bean’s scope. It has two arguments that are value and proxyMode.
- To define a request scope spring bean, set the value argument to WebApplicationContext.SCOPE_REQUEST.
@Scope(value=WebApplicationContext.SCOPE_REQUEST, proxyMode=ScopedProxyMode.TARGET_CLASS)
- To define a session scope spring bean, set the value argument to WebApplicationContext.SCOPE_SESSION.
@Scope(value=WebApplicationContext.SCOPE_SESSION, proxyMode=ScopedProxyMode.TARGET_CLASS)
2. Spring Request Session Scope Bean Example.
- In this example, there is one request scope and one session scope spring bean.
- When browsing the page_one.html web page, it will display the two spring beans create date time. Because it is the first time, so the two scope spring bean create date-time is the same.
- When you click the Click Next link at page_one.html bottom, it will redirect to page_two.html.
- Because the request scope bean has expired, so it will be recreated again, but the session scope bean will not expire. Then the request scope bean’s create time changed while the session scope bean’s create time does not change.
- You can see the demo video on youtube https://youtu.be/3xoypglW_m8.
2.1 Example Source Files.
- Below are the source files for this example spring project.
SpringMVCRequestSession/ ├── pom.xml ├── src │ └── main │ ├── java │ │ └── com │ │ └── dev2qa │ │ └── scope │ │ ├── config │ │ │ ├── ContextConfig.java │ │ │ └── ContextDispatcherServlet.java │ │ ├── controller │ │ │ └── BeanScopeController.java │ │ └── model │ │ ├── RequestScopeBean.java │ │ └── SessionScopeBean.java │ ├── resources │ │ └── config │ │ └── messages.properties │ └── webapp │ └── WEB-INF │ └── views │ ├── page_one.jsp │ └── page_two.jsp └── target ├── classes │ ├── com │ │ └── dev2qa │ │ └── scope │ │ ├── config │ │ │ ├── ContextConfig.class │ │ │ └── ContextDispatcherServlet.class │ │ ├── controller │ │ │ └── BeanScopeController.class │ │ └── model │ │ ├── RequestScopeBean.class │ │ └── SessionScopeBean.class │ └── config │ └── messages.properties ├── m2e-wtp │ └── web-resources │ └── META-INF │ ├── MANIFEST.MF │ └── maven │ └── com.dev2qa │ └── scope │ ├── pom.properties │ └── pom.xml ├── maven-archiver │ └── pom.properties ├── maven-status │ └── maven-compiler-plugin │ ├── compile │ │ └── default-compile │ │ ├── createdFiles.lst │ │ └── inputFiles.lst │ └── testCompile │ └── default-testCompile │ └── inputFiles.lst ├── spring-custom-editor-validator-example │ └── WEB-INF │ ├── classes │ │ ├── com │ │ │ └── dev2qa │ │ │ └── scope │ │ │ ├── config │ │ │ │ ├── ContextConfig.class │ │ │ │ └── ContextDispatcherServlet.class │ │ │ ├── controller │ │ │ │ └── BeanScopeController.class │ │ │ └── model │ │ │ ├── RequestScopeBean.class │ │ │ └── SessionScopeBean.class │ │ └── config │ │ └── messages.properties │ ├── lib │ │ ├── jstl-1.2.jar │ │ ├── spring-aop-5.0.0.BUILD-20170928.094955-624.jar │ │ ├── spring-beans-5.0.0.BUILD-20170928.094955-624.jar │ │ ├── spring-context-5.0.0.BUILD-20170928.094955-624.jar │ │ ├── spring-core-5.0.0.BUILD-20170928.094955-624.jar │ │ ├── spring-expression-5.0.0.BUILD-20170928.094955-624.jar │ │ ├── spring-jcl-5.0.0.BUILD-20170928.094955-444.jar │ │ ├── spring-web-5.0.0.BUILD-20170928.094955-623.jar │ │ ├── spring-webmvc-5.0.0.BUILD-20170928.094955-623.jar │ │ └── standard-1.1.2.jar │ └── views │ ├── page_one.jsp │ └── page_two.jsp └── spring-custom-editor-validator-example.war
2.1.1 ContextConfig.java
- ContextConfig.java
package com.dev2qa.scope.config; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ReloadableResourceBundleMessageSource; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.InternalResourceViewResolver; @EnableWebMvc @Configuration @ComponentScan(basePackages="com.dev2qa.scope") public class ContextConfig extends WebMvcConfigurerAdapter { /* Used to render jsp pages to client. */ @Bean(name = "jspViewResolver") public InternalResourceViewResolver getJspViewResolver() { InternalResourceViewResolver ret = new InternalResourceViewResolver(); // The prefix of the Controller's RequestMapping method returned string. ret.setPrefix("/WEB-INF/views/"); // The suffix of the Controller's RequestMapping method returned string. ret.setSuffix(".jsp"); ret.setOrder(1); return ret; } /* Create a MessageSource bean to get message from message files, for i18n purpose. */ @Bean(name = "messageSource") public MessageSource getMessageSource() { ReloadableResourceBundleMessageSource ret = new ReloadableResourceBundleMessageSource(); /* Set the base name for the messages properties file. All the messages.perperties file are saved in src/main/resources/config folder. */ ret.setBasenames("classpath:config/messages"); ret.setCacheSeconds(1); ret.setUseCodeAsDefaultMessage(true); ret.setDefaultEncoding("utf-8"); return ret; } }
2.1.2 ContextDispatcherServlet.java
- ContextDispatcherServlet.java
package com.dev2qa.scope.config; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration; import org.springframework.context.annotation.Configuration; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; @Configuration public class ContextDispatcherServlet implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext dispatcherServletContext = new AnnotationConfigWebApplicationContext(); dispatcherServletContext.register(ContextConfig.class); DispatcherServlet dispatcherServlet = new DispatcherServlet(dispatcherServletContext); // Create a servlet dynamically. ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", dispatcherServlet); dispatcher.setLoadOnStartup(1); // Add servlet mapping url. All url end with .html will be processed by this servlet. dispatcher.addMapping("*.html"); } }
2.1.3 Controller Java Bean.
- BeanScopeController.java
package com.dev2qa.scope.controller; import java.util.Locale; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.dev2qa.scope.model.RequestScopeBean; import com.dev2qa.scope.model.SessionScopeBean; @Controller @RequestMapping("/scope_bean") public class BeanScopeController { // Inject messageSource, requestScope and sessionScope beans. @Autowired private MessageSource messageSource; @Autowired private RequestScopeBean requestScopeBean; @Autowired private SessionScopeBean sessionScopeBean; @RequestMapping(value="/page_one.html", method=RequestMethod.GET) public String processPageOne(Model model){ String message = messageSource.getMessage("request_scope_bean_description", null, Locale.getDefault()); requestScopeBean.setMessage(message); message = messageSource.getMessage("session_scope_bean_description", null, Locale.getDefault()); sessionScopeBean.setMessage(message); model.addAttribute("requestBean", requestScopeBean); model.addAttribute("sessionBean", sessionScopeBean); return "page_one"; } @RequestMapping(value="/page_two.html", method=RequestMethod.GET) public String processPageTwo(Model model){ // Because request scope bean exist only in one request, so need to set the request scope bean message again. String message = messageSource.getMessage("request_scope_bean_description", null, Locale.getDefault()); requestScopeBean.setMessage(message); model.addAttribute("requestBean", requestScopeBean); model.addAttribute("sessionBean", sessionScopeBean); return "page_two"; } }
2.1.4 Request Scope Bean Java File.
- RequestScopeBean.java
package com.dev2qa.scope.model; import java.util.Date; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import org.springframework.web.context.WebApplicationContext; import org.springframework.context.annotation.ScopedProxyMode; // Declare this is a request scope bean. @Scope(value=WebApplicationContext.SCOPE_REQUEST, proxyMode=ScopedProxyMode.TARGET_CLASS) @Component public class RequestScopeBean { public String message; public Date createDate; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Date getCreateDate() { return createDate; } /* Set createDate when request scope bean is created so that later invoke this method on the same bean will not change the createDate value. */ public RequestScopeBean() { createDate = new Date(); } }
2.1.5 Session Scope Bean Java File.
- SessionScopeBean.java
package com.dev2qa.scope.model; import java.util.Date; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.stereotype.Component; import org.springframework.web.context.WebApplicationContext; //Declare this is a session scope bean. @Scope(value=WebApplicationContext.SCOPE_SESSION, proxyMode=ScopedProxyMode.TARGET_CLASS) @Component public class SessionScopeBean { public String message; public Date createDate; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Date getCreateDate() { return createDate; } /* Set createDate value in session scope bean constructor. Then same session bean createDate value will be same also. */ public SessionScopeBean() { createDate = new Date(); } }
2.1.6 Message Properties File.
- messages.properties
request_scope_bean_description=This is a request scope bean request_scope_bean_create_date=The request scope bean create date is : session_scope_bean_description=This is a session scope bean session_scope_bean_create_date=The session scope bean create date is : page_title=Spring Request Session Scope Bean Example click_next=Click Next
2.1.7 page_one.jsp
- page_one.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <%@ page session="false" %> <html> <head> <title><spring:message code="page_title"></spring:message></title> </head> <body> ${requestBean.message}, <spring:message code="request_scope_bean_create_date"/> ${requestBean.createDate}<br/><br/> ${sessionBean.message}, <spring:message code="session_scope_bean_create_date"/> ${sessionBean.createDate}<br/><br/> <a href="${pageContext.request.contextPath}/scope_bean/page_two.html"><spring:message code="click_next"/></a> </body> </html>
2.1.8 page_two.jsp
- page_two.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <%@ page session="false" %> <html> <head> <title><spring:message code="page_title"></spring:message></title> </head> <body> ${requestBean.message}, <spring:message code="request_scope_bean_create_date"/> ${requestBean.createDate}<br/><br/> ${sessionBean.message}, <spring:message code="session_scope_bean_create_date"/> ${sessionBean.createDate}<br/><br/> </body> </html>
2.1.9 pom.xml
- pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.dev2qa</groupId> <artifactId>scope</artifactId> <name>SpringMVCRequestSession</name> <packaging>war</packaging> <version>1.0.0-BUILD-SNAPSHOT</version> <!-- Spring framework used constants variable --> <properties> <spring.version>5.0.0.BUILD-SNAPSHOT</spring.version> <servlet.api.version>3.1.0</servlet.api.version> </properties> <repositories> <!-- This repository is where the spring framework dependencies jar file download. --> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/libs-snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> <dependencies> <!-- Below dependency is used for servlet and jsp. --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlet.api.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- Below are the basic spring container dependencies library. --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <!-- Below dependency is used for spring mvc framework. --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> </dependencies> <build> <finalName>spring-custom-editor-validator-example</finalName> <plugins> <!-- Because this project do not use web.xml so need below settings. --> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.3</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <username>tomcat</username> <password>tomcat</password> <!-- update true will override the existing deployed war file in tomcat --> <update>true</update> </configuration> </plugin> </plugins> </build> </project>