SpringMvc通過自定義註解在方法的引數中注入資料
阿新 • • 發佈:2019-01-02
說一個場景,有時候我們做後臺業務的時候,經常需要取session中儲存的使用者資訊,所以免不了一直需要寫下面這一段又長又無聊的程式碼:
MemberCommand memberCommand = (MemberCommand) request.getSession().getAttribute(SessionAttr.MEMBER_DETAIL);
那麼怎麼避免這個事情呢,下面我們就來通過一個自定義註解@MemberDetail和SpringMvc的HandlerMethodArgumentResolver介面來實現這個功能。
首先來建立我們的自定義註解:
/**
*
* @Description 方法的引數上加了這個註解,會自動注入當前登入使用者放在session中的使用者物件
* @author chenbin.sun
* @date 2017年8月30日上午11:23:02
*
*/
@Documented
@Target({ ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface MemberDetail {
}
然後實現HandlerMethodArgumentResolver介面,來寫我們的注入邏輯,url請求進來後走完其他一些攔截器等之後會在進入方法之前執行supportsParameter依次傳入要請求方法的引數,我們只需要在這裡判斷這個引數,是否符合我們的要求,是否是我們想要注入的引數就可以了,如果是返回true,否則返回false,如果返回的是true那麼他就會執行resolveArgument方法,此時我們只需要把我們要注入的資料return出去就可以了,詳情請看下面程式碼。
/**
* @Description 用於方法引數上加MemberDetail標籤獲取當前登入使用者的資訊
* @author chenbin.sun
* @date 2017年8月30日下午3:50:00
*
*/
public class MemberDetailHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
/** 登入使用者資訊session中的key */
private String sessionKey = SessionAttr.MEMBER_DETAIL;
/** 登入使用者資訊的class型別 */
private Class<?> sessionMemberClass = MemberCommand.class;
@Override
public boolean supportsParameter(MethodParameter parameter) {
// 過濾出符合條件的引數,這裡指的是加了MemberDetail註解的引數
if (parameter.hasParameterAnnotation(MemberDetail.class)) {
return true;
}
return false;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
// 獲取session中存放的使用者資訊
Object sessionMember = WebUtils.getSessionAttribute(request, sessionKey);
if (null == sessionMember){
return null;
}
// session中物件與加了MemberDetail註解的引數的型別相同是賦值給這個引數
Class<?> klass = parameter.getParameterType();
if (klass.isAssignableFrom(sessionMemberClass)){
return sessionMember;
}
return null;
}
}
當然拉,這個實現類需要在xml中配置一下才能生效,下面看真名配置,很簡單的。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
">
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="chenbin.sun.MemberDetailHandlerMethodArgumentResolver"></bean>
</mvc:argument-resolvers>
</mvc:annotation-driven>
</beans>
使用的時候只需要像下面這樣將註解配置到要注入的引數上,那麼請求進來後,如果session中有這個值,那麼你的方法上的這個引數就一定是有值的了。
@RequestMapping("/doTest")
public String test(@MemberDetail MemberCommand memberCommand){
System.out.println(memberCommand.getName());
}
OK,就到這裡,個人覺得這個還是挺實用的。