为什么bean(具有请求范围)未在控制器中的每个请求中初始化?

时间:2012-11-16 15:12:53

标签: spring spring-mvc spring-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)创建一次不在每个请求中?!!!

2 个答案:

答案 0 :(得分:3)

CGLIB在班级上工作。

CGLIB代理仍然是单例,因此它继承了基类中的字段。更改其公共属性时,您可以更改单例的值。

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

答案 1 :(得分:2)

有点晚了 - 再加上Boris Treukhov的回答(给它+1了):

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

现在,当您将ActionResponse注入到DiscussionController中时,它是注入的CGLIB代理,并且由于您通过setter直接设置字段,因此它只修改代理的字段而不是底层范围的代理对象。修复只是通过getter和setter而不是通过字段进行状态更改。