The scope 'request' defines a single bean definition which lives within a single HTTP request. That means for each HTTP request a new bean instance is created. This scope is only valid in the context of a web-aware ApplicationContext.
This scope might be very useful in using helper objects across multiple beans through out a single request. This is particularly useful as compared to passing various parameters through a long chain of methods calls which sometimes becomes unmaintainable and it's difficult to add new parameters.
Example
Since we are going to inject a 'request' scoped bean into a default 'singleton' scoped bean, we have to avoid narrower scope bean DI problem. For that we will use JSR 330 Provider approach. Here's a list of other solution.
Creating request scoped bean
@Component
@Scope(WebApplicationContext.SCOPE_REQUEST)
public class EmployeeDetails implements Serializable {
private Employee employee;
private int lastYearSalary;
//getters/setters
.............
}
public class Employee {
private String id;
private String name;
private String dept;
public Employee(String id, String name, String dept) {
this.id = id;
this.name = name;
this.dept = dept;
}
//getters/setters
.............
}
Injecting request bean to Controller
@Controller
@RequestMapping("/employees")
public class EmployeeController {
@Autowired
private Provider<EmployeeDetails> employeeDetailsProvider;
@Autowired
AppService appService;
@RequestMapping("/{id}")
public String handler(@PathVariable("id") String employeeId) {
employeeDetailsProvider.get().setEmployee(getEmployeeById(employeeId));
appService.findEmployeeSalary();
return "employee-page";
}
.............
}
Injecting request bean to other beans
@Service
public class AppService {
@Autowired
private Provider<EmployeeDetails> employeeDetailsProvider;
public void findEmployeeSalary() {
EmployeeDetails employeeDetails = employeeDetailsProvider.get();
Employee employee = employeeDetails.getEmployee();
employeeDetails.setLastYearSalary(getEmployeeSalary(employee));
}
.............
}
Output
To try examples, run embedded tomcat (configured in pom.xml of example project below):
mvn tomcat7:run-war
As seen above, all information of EmployeeDetails is there even though they were populated in different places by autowiring. That shows a single instance of EmployeeDetails was used through out the request.
Let's make a different request:
Example ProjectDependencies and Technologies Used: - spring-webmvc 5.0.5.RELEASE: Spring Web MVC.
- javax.servlet-api 3.0.1 Java Servlet API
- javax.inject 1: The javax.inject API.
- JDK 1.8
- Maven 3.3.9
|