首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring RequestScope bean未按预期工作

Spring RequestScope bean未按预期工作
EN

Stack Overflow用户
提问于 2021-07-07 23:22:39
回答 1查看 1.6K关注 0票数 0

我正在尝试学习更多关于Spring作用域的知识,以便在项目中使用。我已经创建了几个测试类,而且我没有得到我所期望的行为。

我创建了下面的组件,我希望这个bean只持续HTTP请求的持续时间。

代码语言:javascript
复制
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserDataContainer {
    
    public int requestCount = 0;

}

下面的控制器使用该组件。

代码语言:javascript
复制
@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。我是否误解了这是如何工作的,还是没有正确地实现。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-07 23:57:18

这里的问题是,您的控制器没有直接调用请求作用域bean。

相反,控制器使用代理来调用请求作用域bean (在本例中,代理是基于代理模式注释(即:ScopedProxyMode.TARGET_CLASS )的cglib代理。

代理只环绕请求作用域bean的方法,而不是它的变量。

因此,简而言之,将请求作用域bean的实例变量封装到一个方法中,并从Controller调用该方法。

就像这样:

代码语言:javascript
复制
@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中,只需调用公共方法

代码语言:javascript
复制
@GetMapping
public String get(Model model) {
    model.addAttribute("prev", userData.getRequestCount());

    model.addAttribute("curr", userData.incrementRequestCount());
    
    return "test";
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68293940

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档