spring mvc中注解@ModelAttribute的妙用分享
前言
本文主要給大家介紹了關(guān)于spring mvc注解@ModelAttribute妙用的相關(guān)內(nèi)容,分享出來供大家參考學(xué)習(xí),下面話不多說了,來一起看看詳細(xì)的介紹吧。
在Spring mvc中,注解@ModelAttribute是一個非常常用的注解,其功能主要在兩方面:
- 運(yùn)用在參數(shù)上,會將客戶端傳遞過來的參數(shù)按名稱注入到指定對象中,并且會將這個對象自動加入ModelMap中,便于View層使用;
- 運(yùn)用在方法上,會在每一個@RequestMapping標(biāo)注的方法前執(zhí)行,如果有返回值,則自動將該返回值加入到ModelMap中;
一般開發(fā)中,第一種用法居多,本次我將使用第二種用法以期節(jié)省controller層的一些代碼:
目前使用spring mvc開發(fā)的controller層方法一般類似于:
@RequestMapping("/{encodeId}/detail") public String detail(ModelMap model, @PathVariable String encodeId) { ..... }
幾乎在每一個@RequestMapping標(biāo)注的方法的參數(shù)中都會有 ModelMap model的參數(shù),既然這是一個大概率事件,為什么不可以像注入request那樣,直接在類的開始使用@Resource進(jìn)行自動注入呢?
另外一個,就是response,response也不能像request那樣進(jìn)行自動注入。
類似的可能還有很多,既然這些都是controller層常用的代碼,如果能將其在一個basecontroller層自動注入,然后controller層繼承這個basecontroller,那樣就沒有必要再@RequestMapping標(biāo)注的方法中寫上這些參數(shù),使得參數(shù)個數(shù)減少,清晰。
我的思路正是使用@ModelAttribute注解,編寫一個basecontroller類,預(yù)定義一些項(xiàng)目中controller層常用的對象,如下:
@Resource protected HttpServletRequest request; protected ModelMap model; protected HttpServletResponse response;
request不用解釋,可以直接使用@Resource直接注入,response和model的注入方式如下:
/** * 設(shè)置response * * @param response */ @ModelAttribute private final void initResponse(HttpServletResponse response) { this.response = response; } /** * 設(shè)置model * * @param model */ @ModelAttribute private final void initModelMap(ModelMap model) { this.model = model; }
spring在執(zhí)行@RequestMapping前會執(zhí)行上述方法,spring會和平常一樣,每次請求重新生成一個model和response,然后注入到方法的參數(shù)中,這樣就變相在繼承了這個basecontroller的controller中自動注入了response和model,在這個controller層中再也不必每次寫ModelMap和response參數(shù),整體代碼整潔了不少。
我在項(xiàng)目中這樣使用暫無問題,如果哪位高手知道這種做法會有弊端或者有更好的方法,求指正!
修正:
非常感謝eBusinessMan的提醒,確實(shí)有可能在spring mvc單例模式下會出現(xiàn)訪問對象不一致的情況,為了防止該問題,而又能保持這種代碼的簡潔性以及確保使用spring mvc性能問題不太嚴(yán)重,我決定使用ThreadLocal來處理。
(驗(yàn)證結(jié)果:request采用spring的自動注入方式是線程安全的,response、model是不安全的,采用ThreadLocal可以解決該問題)
request對象不再使用注解自動注入(也可以繼續(xù)使用注解方式注入),而使用同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); } /** * 獲取當(dāng)前線程的response對象 * * @return */ protected final HttpServletResponse getResponse() { return responseContainer.get(); } /** * 初始化request * * @param request */ @ModelAttribute private final void initRequest(HttpServletRequest request) { requestContainer.set(request); } /** * 獲取當(dāng)前線程的request對象 * * @return */ protected final HttpServletRequest getRequest() { return requestContainer.get(); } /** * 設(shè)置model * * @param model */ @ModelAttribute private final void initModelMap(ModelMap model) { modelContainer.set(model); } /** * 獲取當(dāng)前線程的modelMap對象 * * @return */ protected final ModelMap getModelMap() { return modelContainer.get(); }
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
深入探究Java中的HashMap為什么會產(chǎn)生死循環(huán)
HashMap?死循環(huán)發(fā)生在?JDK?1.8?之前的版本中,這篇文章主要來和大家深入探究一下為什么Java中HashMap會產(chǎn)生死循環(huán),感興趣的小伙伴可以了解一下2023-05-05關(guān)于MyBatis的foreach標(biāo)簽常用方法
這篇文章主要介紹了關(guān)于MyBatis的foreach標(biāo)簽常用方法,foreach 標(biāo)簽可以用來遍歷數(shù)組、列表和 Map 等集合參數(shù),實(shí)現(xiàn)批量操作或一些簡單 SQL 操作,需要的朋友可以參考下2023-05-05使用迭代器模式來進(jìn)行Java的設(shè)計(jì)模式編程
這篇文章主要介紹了使用迭代器模式來進(jìn)行Java的設(shè)計(jì)模式編程,文中對迭代器模式中的容器封裝方面的知識進(jìn)行了講解,需要的朋友可以參考下2016-02-02java開發(fā)工作中對InheritableThreadLocal使用思考
這篇文章主要為大家介紹了java開發(fā)工作中對InheritableThreadLocal使用思考詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11MybatisPlus中QueryWrapper常用方法總結(jié)
MyBatis-Plus是一個Mybatis增強(qiáng)版工具,在MyBatis上擴(kuò)充了其他功能沒有改變其基本功能,為了簡化開發(fā)提交效率而存在,queryWrapper是mybatis plus中實(shí)現(xiàn)查詢的對象封裝操作類,本文就給大家總結(jié)了MybatisPlus中QueryWrapper的常用方法,需要的朋友可以參考下2023-07-07