zoukankan      html  css  js  c++  java
  • 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")
  • 相关阅读:
    3Sum Closest
    二叉树的下一个结点
    数组中重复的数字
    不用加减乘除做加法
    和为S的连续正数序列
    数组中只出现一次的数字
    求二叉树的是否为平衡二叉树
    由一道很简单的求两条链表的第一个公共节点的问题引发的思考
    第14章 网络编程
    第13章 文档与串行化
  • 原文地址:https://www.cnblogs.com/milton/p/4855694.html
Copyright © 2011-2022 走看看