因为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")

SpringMVC的Controller中使用线程安全的初始化的更多相关文章

  1. springmvc的controller中使用@Transactional无效

    最近看mybatis的时候做了一个练习,但是进行事务处理的时候出了问题,如下 package com.henu.lz.controller; import org.springframework.be ...

  2. springmvc 解决 controller 中出现死循环并 stackoverflow 的问题

    这是因为这个controller中的方法返回值为void类型,且没有request response这类衍生的重定向,或者返回值为String,但是是null等等的情况,都会引起死循环,然后stack ...

  3. 在springMVC的controller中获取request,response对象的一个方法

    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttr ...

  4. springMVC:将controller中数据传递到jsp页面

    1> 将方法的返回值该为ModelAndView在返回时,将数据存储在ModelAndView对象中如: newModelAndView("/WEBINF/jsp/showData.j ...

  5. 9.SpringMVC和json结合传递数据 && 10.SpringMVC获取controller中json的数据

  6. 聊聊Servlet、Struts1、Struts2以及SpringMvc中的线程安全

    前言 很多初学者,甚至是工作1-3年的小伙伴们都可能弄不明白?servlet Struts1 Struts2 springmvc 哪些是单例,哪些是多例,哪些是线程安全? 在谈这个话题之前,我们先了解 ...

  7. SpringMVC Controller中注入Request成员域和在方法中定义中HttpServletRequest有啥区别

    先说结论,在Controller中注入Request是线程安全的. 以下是解释: 我们先来看看这两者有什么不同 在controller注入成员变量request 可以看到注入的是一个代理对象 写在方法 ...

  8. (转)聊聊Servlet、Struts1、Struts2以及SpringMvc中的线程安全

    前言 很多初学者,甚至是工作1-3年的小伙伴们都可能弄不明白?servlet Struts1 Struts2 springmvc 哪些是单例,哪些是多例,哪些是线程安全? 在谈这个话题之前,我们先了解 ...

  9. SpringMVC之八:基于SpringMVC拦截器和注解实现controller中访问权限控制

    SpringMVC的拦截器HandlerInterceptorAdapter对应提供了三个preHandle,postHandle,afterCompletion方法. preHandle在业务处理器 ...

随机推荐

  1. 【Android】用MediaRecorder录制视频太短崩的问题

    具体表现: 调用MediaRecorder的start()与stop()间隔不能小于1秒(有时候大于1秒也崩),否则必崩. 错误信息: java.lang.RuntimeException: stop ...

  2. js DOM Node类型

    DOM(文档对象模型)是针对HTML和XML文档的一个API. DOM可以将任何HTML或XML文档描绘成一个由多层节点构成的.以特定节点为根节点的树形结构.节点分为12种不同的类型,每种类型分别表示 ...

  3. github邮箱验证技巧

    申请的github账号,绑定邮箱之后才能创建库,而反复几次的发送邮件均为收到验证邮件,猜测有两个原因: 1.腾讯邮件服务器屏蔽了github的来信 (腾讯不会这么狭隘的,×) 2.自己邮箱的域名黑名单 ...

  4. Asp.net MVC的Model Binder工作流程以及扩展方法(3) - DefaultModelBinder

    Default Binder是MVC中的清道夫,把守着Model Binder中的最后一道防线.如果我们没有使用Custom Model Binder等特殊处理,那么Model的绑定都是有Defaul ...

  5. 今天说一下where 中 exists 和 in 里面的一些区别

    in 和 exists 已经成为我们日常查询时候的常客了.很多时候他们2个都是可以互通实现的,但是,无论兄弟怎么亲,还是会有那么一些差别的. 先搞个测试表 )) ),Col2 )) INSERT IN ...

  6. Linux 内核日志——dmesg

    有时Linux系统或者系统上运行的mysqld或者其它进程,会发生一些莫名其妙的问题,比如突然挂掉了,比如突然重启等等.在软件上找不到问题所在,此时我们应该怀疑硬件或者内核的问题,此时我们就可以使用 ...

  7. mysql学习笔记(一)

    my建表操作 创建表 create Table <表名> ( 字段名1,数据类型 [列级约束] [默认值], 字段名2,数据类型 [列级约束] [默认值], ... [表级约束], [co ...

  8. pl/sql developer——instant-client 简单配置

    instant-client(数据库即时客户端) 官方说明:即时客户端在一个单独的针对 Instant Client 的 OTN 开发和分发许可下提供,它允许大多数许可下载.重新分发和部署到生产环境中 ...

  9. 常用的js跳转页面方法实现汇总

    1.window.location.href方式 <script language="javascript" type="text/javascript" ...

  10. Linux学习--------一

    用户不能直接操作Kemel,所以需要通过Shell来操作Kemel(内核) Shell 分为CLI与GUI两种 CLI:Command Line Interface GUI:Graphical Use ...