spring mvc中注解@ModelAttribute的妙用分享
前言
本文主要给大家介绍了关于spring mvc注解@modelattribute妙用的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。
在spring mvc中,注解@modelattribute是一个非常常用的注解,其功能主要在两方面:
- 运用在参数上,会将客户端传递过来的参数按名称注入到指定对象中,并且会将这个对象自动加入modelmap中,便于view层使用;
- 运用在方法上,会在每一个@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的妙用分享
-
spring mvc中的@ModelAttribute注解示例介绍
-
spring mvc中注解@ModelAttribute的妙用分享
-
spring mvc中的@ModelAttribute注解示例介绍
-
Spring MVC中基于自定义Editor的表单数据处理技巧分享
-
Spring MVC中基于自定义Editor的表单数据处理技巧分享
-
spring mvc4中相关注解的详细讲解教程
-
spring mvc4中相关注解的详细讲解教程
-
关于Spring mvc中modelattribute无法制定别名的解决方案
-
关于Spring mvc中modelattribute无法制定别名的解决方案