spring的annotation-driven

argument resolvers


  1.   spring的請求處理都是方法級別,圍繞方法上的處理,當你須要針對請求參數作一些特殊的處理,不一樣的類型得到不一樣的處理。我這邊項目有一個需求是在controller裏面得到session裏面的用戶信息,咱們普通採用的方法是直接從session裏面獲取,須要指定具體的key。從裏面得到,若是調用登陸用戶的地方不少的時候,處理的邏輯也是至關冗餘的。
  2. 這邊利用spring的argument resolvers(參數解析),針對自定義註解來注入用戶到方法級別。

     先定義註解: java


@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface UserAttribute {
}



裏面能夠擴展你須要對用戶處理的邏輯。


在是實現spring的HandlerMethodArgumentResolver --這個接口是操做處理方法的參數處理。 web

spring在處理請求參數時,針對不一樣註解或者不一樣類型例如HttpRequest,HttpResponse的值的賦值。默認都是有一個組合的處理器,註冊一些默認的處理方式,我下面把註冊的地方添加進來。 spring

在RequestMappingHandlerAdapter類裏面的afterPropertiesSet方法裏面。 session

public void afterPropertiesSet() {
		// Do this first, it may add ResponseBody advice beans
		initControllerAdviceCache();
                //請求參數初始的解析器
             if (this.argumentResolvers == null) {
			List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
			this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
		}
                //初始綁定參數的解析器
		if (this.initBinderArgumentResolvers == null) {
			List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
			this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
		}
                //初始方法返回值的包裝器
		if (this.returnValueHandlers == null) {
			List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
			this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
		}
	}


每個都有一個默認配置,如下是請求參數的默認解析器。 app

private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
		List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>();

		// Annotation-based argument resolution
		resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false)); --@requestParam註解
		resolvers.add(new RequestParamMapMethodArgumentResolver());
		resolvers.add(new PathVariableMethodArgumentResolver());--@pathVariable註解
		resolvers.add(new PathVariableMapMethodArgumentResolver());
		resolvers.add(new MatrixVariableMethodArgumentResolver());
		resolvers.add(new MatrixVariableMapMethodArgumentResolver());
		resolvers.add(new ServletModelAttributeMethodProcessor(false));
		resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
		resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));
		resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
		resolvers.add(new RequestHeaderMapMethodArgumentResolver());
		resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
		resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));

		// Type-based argument resolution
		resolvers.add(new ServletRequestMethodArgumentResolver());
		resolvers.add(new ServletResponseMethodArgumentResolver());
		resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
		resolvers.add(new RedirectAttributesMethodArgumentResolver());
		resolvers.add(new ModelMethodProcessor());
		resolvers.add(new MapMethodProcessor());
		resolvers.add(new ErrorsMethodArgumentResolver());
		resolvers.add(new SessionStatusMethodArgumentResolver());
		resolvers.add(new UriComponentsBuilderMethodArgumentResolver());

		// Custom arguments
                // 添加自定義解析器
		if (getCustomArgumentResolvers() != null) {
			resolvers.addAll(getCustomArgumentResolvers());
		}

		// Catch-all
		resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
		resolvers.add(new ServletModelAttributeMethodProcessor(true));

		return resolvers;
	}



感興趣的話能夠這些請求參數的解析方式都看一下,瞭解一下每個種類型的解析方式。


迴歸正題,咱們如今集成接口後須要實現兩個方法。 ui

supportsParameter 和 resolveArgument,默認自定義的解析器是在最後面。判斷supportsParameter支持是否爲true,若是爲true就走下面resolveArgument方法, this

裏面返回值就是你須要處理的對象,須要封裝你本身的處理邏輯針對註解。 spa

public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        HttpSession session = request.getSession();

        UserInfo user = (UserInfo)session.getAttribute(Constant.USER_INFO_SESSION);

        return user;
    }



這樣就能經過註解在方法上獲取到登陸的用戶信息。

return-value-handlers的處理方式在spring裏面仍是有一點不同。下面會介紹。 code

相關文章
相關標籤/搜索