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")
  • 相关阅读:
    求一个二维数组的最大子矩阵
    在一整型数组中找到此数组中子数组和的最大值
    软件工程个人小项目:写一个程序,分析一个文本文件(英文文章)中各个词出现的频率,并且把频率最高的10个词打印出来
    Redis 为什么这么快?
    在netfarmerwork3.5版本的winform下执行string串中的代码
    c# 反射(Reflection)详解
    string,特殊的引用类型
    c#使用HashSet<T>集合去重
    c# .Net重试机制
    观察者模式
  • 原文地址:https://www.cnblogs.com/milton/p/4855694.html
Copyright © 2011-2022 走看看