在開發(fā)中,經(jīng)常會用到在控制層的對外請求接口入?yún)⒅?,希望通過一個注解來注入當(dāng)前登錄用戶信息,從而在接口功能下行過程中,能夠一直傳下去,來實(shí)現(xiàn)用戶信息的獲取

spring參數(shù)解析器,讓你的方法入?yún)⒏鼉?yōu)雅
曾幾何時,我們編程從原始時代進(jìn)入石器時代,開始擁有使用工具的思想,于是大量的工具,util和腳手架開始像雨后春筍似的出現(xiàn),spring字如其名,像春天一樣,奠定了萬物復(fù)蘇的基石,于是基于spring的大量框架開始出現(xiàn),如springMvc,springboot,springcloud等,生態(tài)一時無兩。作為使用spring多年的老用戶,總是會好奇我們在使用開發(fā)的各種功能,于是像貓一樣的探索,挖掘,模仿讓人著謎的各種設(shè)計。今天分享參數(shù)解析器,實(shí)現(xiàn)像@RequestBody一樣的功能,一個注解自動注入想要參數(shù)的方法解析器實(shí)戰(zhàn)。廢話不多說,直接上代碼!
功能背景描述:
在開發(fā)中,經(jīng)常會用到在控制層的對外請求接口入?yún)⒅?,希望通過一個注解來注入當(dāng)前登錄用戶信息,從而在接口功能下行過程中,能夠一直傳下去,來實(shí)現(xiàn)用戶信息的獲取
實(shí)現(xiàn)步驟如下:
定義當(dāng)前登錄用戶類 CurrentUser:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 描述:當(dāng)前登錄用戶 </br>
* 作者:IT學(xué)習(xí)道場 </br>
* 時間:2022-11-15 19:07
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CurrentUser {
private Long userId;
private String userName;
}
自定義注解:
import java.lang.annotation.*;
/**
* 描述:自定義用戶注解 </br>
* 作者:IT學(xué)習(xí)道場 </br>
* 時間:2022-11-15 16:56
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WlcUser {
}
當(dāng)前用戶解析器:
import com.example.demo.annotation.WlcUser;
import com.example.demo.po.CurrentUser;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
/**
* 描述:當(dāng)前用戶解析器 </br>
* 作者:IT學(xué)習(xí)道場 </br>
* 時間:2022-11-15 17:01
*/
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
//方法參數(shù)是否帶有 WlcUser注解,帶的話就解析執(zhí)行下方 resolveArgument 方法
return parameter.hasParameterAnnotation(WlcUser.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
//1 這里面可以從httpHeader中獲取用戶標(biāo)識或者其他屬性值,也可以通過springIoc中bean來執(zhí)行增刪改查,rpc來獲取,但是要用spring的上下文來獲取bean
//2 也可以從token中解析出當(dāng)前登錄用戶信息,返回也行對象 CurrentUser
//3 也可以從你自己定義的用戶上下文中獲取 CurrentUser,前提你要自己寫一個用戶上下文
//4 這里調(diào)用sprinIoc里管理的bean的話,需要 SpringContextUtil上下文來獲取bean,在調(diào)用方法
//5 這里只是自己new了一個當(dāng)前用戶,來直接賦予加了 WlcUser 注解修飾的對象
CurrentUser currentUser = new CurrentUser(1L,"老王");
return currentUser;
}
}
把參數(shù)解析器注入到mvc中:
import com.example.demo.resolver.CurrentUserMethodArgumentResolver;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
/**
* 描述:web攔截器,解析器配置類 </br>
* 作者:IT學(xué)習(xí)道場 </br>
* 時間:2022-11-15 19:09
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new CurrentUserMethodArgumentResolver());
}
}
現(xiàn)在測試controller測試實(shí)現(xiàn):
import com.example.demo.annotation.WlcUser;
import com.example.demo.po.CurrentUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 描述:參數(shù)解析解TestController </br>
* 作者:IT學(xué)習(xí)道場 </br>
* 時間:2022-11-16 9:25
*/
@Slf4j
@RestController
@RequestMapping("/currentUserResolver")
public class CurrentUserResolverController {
@GetMapping("/currentUserResolve")
public void currentUserResolve(@WlcUser CurrentUser user){
log.info("參數(shù)解析器注入 CurrentUser = {}", user.toString());
}
}
請求下,控制臺日志:

參數(shù)解析自動注入成功!自己動手豐衣足食,去玩玩吧!