因为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 加载大图片到内存

    本文演示android中图片加载到内存 首先设计界面: 代码如下: <LinearLayout xmlns:android="http://schemas.android.com/ap ...

  2. 不用画线 设置UITableView的全屏分隔线

    如图  添加如下代码 sTableView.separatorInset = UIEdgeInsetsZero; sTableView.layoutMargins = UIEdgeInsetsZero ...

  3. iOS 简单动画 序列帧动画

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ NSLog(@"旭宝爱吃 ...

  4. Http协议与TCP协议简单理解

    TCP协议对应于传输层,而HTTP协议对应于应用层,从本质上来说,二者没有可比性.Http协议是建立在TCP协议基础之上的,当浏览器需要从服务器获取网页数据的时候,会发出一次Http请求.Http会通 ...

  5. yii2 GridView 日期格式化并实现日期可搜索 案例

    作者:白狼 出处:http://www.manks.top/article/yii2_gridview_dateformat_search 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且 ...

  6. bootstrap的编辑标记 angularjs input 弹出框

    .html <div> {{instance.description}} <span class="glyphicon glyphicon-pencil btn-link& ...

  7. Linux服务器文件删除空间未释放的问题

    一.问题起源 在Linux系统中,通过rm删除文件将会从文件系统的目录结构上解除链接(unlink),如果文件是被打开的(有一个进程正在使用),那么进程将仍然可以读取该文件磁盘空间也一直被占用 这样就 ...

  8. c# 请求api获得json数据

    public static string HttpGet(string Url) { HttpWebRequest request = (HttpWebRequest)WebRequest.Creat ...

  9. Linux 引导修复

    前些天,我的Ubuntu老提示"Filesystem root"空间不足,于是,我煞笔的用win pe去扩展空间,结果,空间扩展不成,反倒丢失了引导..... 于是就上网查资料,看 ...

  10. 烂泥:学习ssh之ssh无密码登陆

    本文由秀依林枫提供友情赞助,首发于烂泥行天下 最近一个月没有写过文章,主要是刚刚换的新工作.新公司服务器OS使用的是ubuntu server版,和以前熟悉的centos还是有很多不同的. 刚好这几天 ...