我正在尝试学习更多关于Spring作用域的知识,以便在项目中使用。我已经创建了几个测试类,而且我没有得到我所期望的行为。
我创建了下面的组件,我希望这个bean只持续HTTP请求的持续时间。
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserDataContainer {
public int requestCount = 0;
}下面的控制器使用该组件。
@Controller
@RequestMapping("/hello")
public class HelloController {
@Autowired
private UserDataContainer userData;
@GetMapping
public String get(Model model) {
model.addAttribute("prev", userData.requestCount);
userData.requestCount++;
model.addAttribute("curr", userData.requestCount);
return "test";
}
}我的问题是,似乎没有为每个请求创建一个新的UserDataContainer实例。无论何时加载此页面,我都会看到"prev“和"curr”的值不断增加,而不是在每个请求开始时重置为0。我是否误解了这是如何工作的,还是没有正确地实现。
发布于 2021-07-07 23:57:18
这里的问题是,您的控制器没有直接调用请求作用域bean。
相反,控制器使用代理来调用请求作用域bean (在本例中,代理是基于代理模式注释(即:ScopedProxyMode.TARGET_CLASS )的cglib代理。
代理只环绕请求作用域bean的方法,而不是它的变量。
因此,简而言之,将请求作用域bean的实例变量封装到一个方法中,并从Controller调用该方法。
就像这样:
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserDataContainer {
private int requestCount = 0;
public int incrementRequestCount(){
requestCount++;
return requestCount;
}
public int getRequestCount(){
return requestCount;
}
} 然后在Controller中,只需调用公共方法
@GetMapping
public String get(Model model) {
model.addAttribute("prev", userData.getRequestCount());
model.addAttribute("curr", userData.incrementRequestCount());
return "test";
}https://stackoverflow.com/questions/68293940
复制相似问题