在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. git 安装 和 基本操作

    林纳斯的小故事 感兴趣的同学可以自己百度一下 版本控制常用svn git @@@svn 1 搭建环境 server:visualSVN Serverserver port: https 默认443ht ...

  2. ArrayList的实现细节(基于JDK1.8)

    ArrayList是我们经常用到的一个类,下面总结一下它内部的实现细节和使用时要注意的地方. 基本概念 ArrayList在数据结构的层面上讲,是一个用数组实现的list,从应用层面上讲,就是一个容量 ...

  3. python 排序sorted

    num = [3,2,4,6,5] anum = sorted(num) dnum = sorted(num,reverse=True) print '升序:',anum # 升序: [2, 3, 4 ...

  4. Scrapy提取多个标签的text

    对于要提取嵌套标签所有内容的情况, 使用string或//text(), 注意两者区别 >>> from scrapy import Selector >>> &g ...

  5. 用u盘启动计算机

    上次只是做好了u盘启动盘,但是并没有说怎么安装系统.接下来说一下怎么装系统.链接:怎么把系统装进u盘(ultraiso) 电脑经常要用到u盘启动.设置u盘启动在bios设置里面进行设置.下面就来讲解一 ...

  6. Hadoop 新生报道(二) hadoop2.6.0 集群系统版本安装和启动配置

    本次基于Hadoop2.6版本进行分布式配置,Linux系统是基于CentOS6.5 64位的版本.在此设置一个主节点和两个从节点. 准备3台虚拟机,分别为: 主机名 IP地址 master 192. ...

  7. github 上传下载代码简单使用

    很长时间,一直认为github很难操作,其实认真学了发现也不是很困难. 主要就3个命令 git clone 建立空间 git push 提交代码,git pull拉取代码. git clone htt ...

  8. 【待整理】MySQL alter table modify vs alter table add产生state不一样

    MySQL:5.6.35 OS:redhat5.8 今天更新数据库某些表字段,有如下两SQL: ①alter table xx modify xxxx;(表大概是77w) ②alter table s ...

  9. 利用Java随机,生成随机学生数据

    为模拟向数据库中大量插入学生数据(注:此处应该用PreparedStatement.batchUpdate等批处理提高效率)的情形,通过Java随机来生成学生数据. 一.要生成的学生数据 studen ...

  10. 浅谈JS中的高级函数

    在JavaScript中,函数的功能十分强大.它们是第一类对象,也可以作为另一个对象的方法,还可以作为参数传入另一个函数,不仅如此,还能被一个函数返回!可以说,在JS中,函数无处不在,无所不能,堪比孙 ...