SpringMVC的Controller中使用线程安全的初始化

因为SpringMVC的Controller默认是单例, 在这种情况下, Controller中使用的私有变量必须也是单例, 例如各种service, 否则会有多线程访问数据互相修改的问题.

对于需要对一类Controller做相同初始化的需求, 可以通过@ModelAttribute("some-variable") public init() 这样的方法解决.

首先创建一个基类如BasicController, 构造一个拦截器, 对基类实现preHandle(), postHandle()方法

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
            Exception exception) throws Exception
    {
        RequestBean requestBean = (RequestBean)request.getAttribute(RequestBean.ATTR_KEY);
        if (requestBean != null)
        {
            requestBean.destroy();
            request.removeAttribute(RequestBean.ATTR_KEY);
            long current = System.currentTimeMillis();
            logger.debug("Page end: " + current + ", time: " + (current - requestBean.getTimestamp()) + " milliseconds");
        }
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView mav) throws Exception
    {
        if (handler instanceof HandlerMethod && mav != null)
        {
            HandlerMethod hm = (HandlerMethod)handler;
            if (BasicController.class.isAssignableFrom(hm.getBean().getClass()))
            {
                mav.addObject("sys_config", Config.getConfigs());
            }
        }
    }

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
    {
        long timestamp = System.currentTimeMillis();
        logger.debug("Page start: " + timestamp);

        if (handler instanceof HandlerMethod)
        {
            HandlerMethod hm = (HandlerMethod)handler;
            if (BasicController.class.isAssignableFrom(hm.getBean().getClass()))
            {
                RequestBean requestBean = new RequestBean(request, response, timestamp);
                request.setAttribute(RequestBean.ATTR_KEY, requestBean);
            }
        }
        return true;
    }

然后在BasicController中, 通过如下形式对每次访问作初始化

    @ModelAttribute("requestBean")
    public RequestBean initRequest(HttpServletRequest request) {
        return (RequestBean)request.getAttribute(RequestBean.ATTR_KEY);
    }

然后在Controller方法中, 就可以直接引用这个初始化好的变量了

@RequestMapping(value = {"/edit","/add"}, method = RequestMethod.GET)
public String doEdit(
        @ModelAttribute("requestBean") RequestBean rb)
{
  ...
}

 

@ModelAttribute("requestBean")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值