在Spring mvc中,注解@ModelAttribute是一个非常常用的注解,其功能主要在两方面:

  1. 运用在参数上,会将客户端传递过来的参数按名称注入到指定对象中,并且会将这个对象自动加入ModelMap中,便于View层使用;
  2. 运用在方法上,会在每一个@RequestMapping标注的方法前执行,如果有返回值,则自动将该返回值加入到ModelMap中;

一般开发中,第一种用法居多,本次我将使用第二种用法以期节省controller层的一些代码:

目前使用spring mvc开发的controller层方法一般类似于:

  @RequestMapping("/{encodeId}/detail")
public String detail(ModelMap model, @PathVariable String encodeId) {
.....
}

几乎在每一个@RequestMapping标注的方法的参数中都会有 ModelMap model的参数,既然这是一个大概率事件,为什么不可以像注入request那样,直接在类的开始使用@Resource进行自动注入呢?

另外一个,就是response,response也不能像request那样进行自动注入。

类似的可能还有很多,既然这些都是controller层常用的代码,如果能将其在一个basecontroller层自动注入,然后controller层继承这个basecontroller,那样就没有必要再@RequestMapping标注的方法中写上这些参数,使得参数个数减少,清晰。

我的思路正是使用@ModelAttribute注解,编写一个basecontroller类,预定义一些项目中controller层常用的对象,如下:

     @Resource
protected HttpServletRequest request; protected ModelMap model; protected HttpServletResponse response;

request不用解释,可以直接使用@Resource直接注入,response和model的注入方式如下:

     /**
* 设置response
*
* @param response
*/
@ModelAttribute
private final void initResponse(HttpServletResponse response) {
this.response = response;
} /**
* 设置model
*
* @param model
*/
@ModelAttribute
private final void initModelMap(ModelMap model) {
this.model = model;
}

spring在执行@RequestMapping前会执行上述方法,spring会和平常一样,每次请求重新生成一个model和response,然后注入到方法的参数中,这样就变相在继承了这个basecontroller的controller中自动注入了response和model,在这个controller层中再也不必每次写ModelMap和response参数,整体代码整洁了不少。

我在项目中这样使用暂无问题,如果哪位高手知道这种做法会有弊端或者有更好的方法,求指正!


修正

  非常感谢eBusinessMan的提醒,确实有可能在spring mvc单例模式下会出现访问对象不一致的情况,为了防止该问题,而又能保持这种代码的简洁性以及确保使用spring mvc性能问题不太严重,我决定使用ThreadLocal来处理。(后期验证是否会出现该问题在本文进行补充)

(验证结果:request采用spring的自动注入方式是线程安全的,response、model是不安全的,采用ThreadLocal可以解决该问题)

request对象不再使用注解自动注入(也可以继续使用注解方式注入),而使用同response和model初始化的方式,取消request、response、model三个类变量,具体如下:

   private static final ThreadLocal<HttpServletRequest> requestContainer = new ThreadLocal<HttpServletRequest>();

   private static final ThreadLocal<HttpServletResponse> responseContainer = new ThreadLocal<HttpServletResponse>();

   private static final ThreadLocal<ModelMap> modelContainer = new ThreadLocal<ModelMap>();

     /**
* 初始化response
*
* @param response
*/
@ModelAttribute
private final void initResponse(HttpServletResponse response) {
responseContainer.set(response);
} /**
* 获取当前线程的response对象
*
* @return
*/
protected final HttpServletResponse getResponse() {
return responseContainer.get();
} /**
* 初始化request
*
* @param request
*/
@ModelAttribute
private final void initRequest(HttpServletRequest request) {
requestContainer.set(request);
} /**
* 获取当前线程的request对象
*
* @return
*/
protected final HttpServletRequest getRequest() {
return requestContainer.get();
} /**
* 设置model
*
* @param model
*/
@ModelAttribute
private final void initModelMap(ModelMap model) {
modelContainer.set(model);
} /**
* 获取当前线程的modelMap对象
*
* @return
*/
protected final ModelMap getModelMap() {
return modelContainer.get();
}

spring mvc:注解@ModelAttribute妙用的更多相关文章

  1. Spring MVC 中 @ModelAttribute 注解的妙用

    Spring MVC 中 @ModelAttribute 注解的妙用 Spring MVC 提供的这种基于注释的编程模型,极大的简化了 web 应用的开发.其中 @Controller 和 @Rest ...

  2. Spring MVC注解的一些案列

    1.  spring MVC-annotation(注解)的配置文件ApplicationContext.xml <?xml version="1.0" encoding=& ...

  3. spring mvc(注解)上传文件的简单例子

    spring mvc(注解)上传文件的简单例子,这有几个需要注意的地方1.form的enctype=”multipart/form-data” 这个是上传文件必须的2.applicationConte ...

  4. spring mvc 注解入门示例

    web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi=" ...

  5. spring mvc 注解示例

    springmvc.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...

  6. 关于Spring mvc注解中的定时任务的配置

    关于spring mvc注解定时任务配置 简单的记载:避免自己忘记,不是很确定我理解的是否正确.有错误地方望请大家指出. 1,定时方法执行配置: (1)在applicationContext.xml中 ...

  7. spring mvc 注解@Controller @RequestMapping @Resource的详细例子

    现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不过 ...

  8. spring mvc之@ModelAttribute注解

    1.@ModelAttribute注释void返回值的方法 @Controller public class HelloModelController { @ModelAttribute public ...

  9. Spring MVC 注解[转]

    [学习笔记]基于注解的spring3.0.x MVC学习笔记(九) 摘要: 本章节,仅为@SessionAttributes的功能扩展介绍介绍,结合@requestparam注解进行简易无数据库分页. ...

随机推荐

  1. angularjs 动态显示内容适用于$modal

    1.创建指令 angular.module('app').directive('dynamicElement', ["$compile", function ($compile) ...

  2. Orchard 学习

    https://github.com/OrchardCMS/Orchard  源码下载 http://www.orchardch.com/  中文介绍网站

  3. pwnable.kr col之write up

    Daddy told me about cool MD5 hash collision today. I wanna do something like that too! ssh col@pwnab ...

  4. PHP输出函数print, printf, sprintf的区别

    PHP中常用的字符串输出方式是:使用echo和print两种方法来显示字符串.如果涉及格式化输出操作,还可以试用printf和sprintf函数. 一.先说echo和print两种方法 print的语 ...

  5. python爬煎蛋妹子图--20多行代码搞定煎蛋妹子图库

    如果说一个人够无聊的话... 就会做一些十分美(wei)丽(suo)的事情啦哈哈哈... 好的,话不多说,进入正题. 正如标题所示,我们今天的目标很简单: 代码要少,妹子要好. 步骤如下: 1. 首先 ...

  6. TCP/IP拥塞控制

    TCP/IP拥塞控制包括:慢启动和拥塞避免.其操作流程如下所述: 初始化.拥塞窗口cwnd = 1,慢启动门限ssthresh = 65535 如果没有发生拥塞 若 cwnd < ssthres ...

  7. Python优缺点

    优点 简单----Python是一种代表简单主义思想的语言.阅读一个良好的Python程序就感觉像是在读英语一样,尽管这个英语的要求非常严格!Python的这种伪代码本质是它最大的优点之一.它使你能够 ...

  8. HTML相关知识

    1 Day01HTML HTML5声明:<!doctype html> <html> 1.1 HTML基本结构: <head> <title>题目< ...

  9. Mybatis源码分析-BaseExecutor

    根据前文Mybatis源码分析-SqlSessionTemplate的简单分析,对于SqlSession的CURD操作都需要经过Executor接口的update/query方法,本文将分析下Base ...

  10. CentOS6 安装Sendmail + Dovecot + Squirrelmail

    本文记录在本地虚拟机CentOS6上搭建Sendmail + Dovecot + Squirrelmail 的Webmail环境的过程,仅仅是本地局域网的环境测试,不配置DNS, 也没有安全认证,Sq ...