3

我的 ActionResponse 代码是:

@Component
@Scope(value = "request",proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ActionResponse{
   public int a;
//body
}

我的控制器:

@Controller
@RequestMapping(value="/ajax/discussion")
public class DiscussionController extends AbstractController {

    @Autowired
    private ActionResponse actionResponse;

    public void setActionResponse(ActionResponse actionResponse) {
        this.actionResponse = actionResponse;
    }

    @RequestMapping("/test")
    public @ResponseBody String test(){
        String response=this.actionResponse.a+"";
        if(this.actionResponse.a==0)
            this.actionResponse.a=10;
        return response;
    }

}

我启动项目,然后第一次请求 /ajax/discussion/test 它显示 0

但之后对于其他请求,它显示 10

由于 ActionResponse 的请求范围,它必须在每个请求中显示 0

问题是:为什么不是在每个请求中都创建一次 bean(ActionResponse)?!!!

4

2 回答 2

3

CGLIB 在班级级别上工作。

CGLIB 代理仍然是一个单例,所以它从基类继承了字段。当您更改其公共属性时,您会更改单例的值。

您应该将数据更改封装在公共 getter 和 setter 中。

于 2012-11-16T15:33:59.817 回答
2

有点晚了 - 只是添加了鲍里斯·特鲁霍夫的答案(已经 +1 了):

原因是由于您使用@Scope(proxyMode=..)Spring 注释了 ActionResponse 最终会创建此 ActionResponse 的 CGLIB 子类,该子类在内部适当地处理范围。

现在,当您将 ActionResponse 注入 DiscussionController 时,注入的是 CGLIB 代理,并且由于您通过 setter 直接设置字段,因此它只是修改了代理的字段,而不是底层作用域代理对象。解决方法是通过 getter 和 setter 而不是通过字段进行状态更改。

于 2012-11-16T15:36:07.537 回答