1. 程式人生 > >Spring boot 自定義註解 簡單版本解析引數

Spring boot 自定義註解 簡單版本解析引數

背景:

其實就是想用一個註解,來統一處理獲取userid的解析過程。 嗯,但是我覺得自己對註解也沒有那麼瞭解,所以再記錄下。

spring boot 中自定義註解的方案:

STEP1. 定義註解

STEP2. 註解解析

1. 定義註解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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

看起來很簡單哈哈

簡單說明下 

@Target說明了Annotation所修飾的物件範圍。 就是這個註解可以用在什麼地方。ElementType)有:

  • CONSTRUCTOR:用於描述構造器
  • FIELD:用於描述域
  • LOCAL_VARIABLE:用於描述區域性變數
  • METHOD:用於描述方法
  • PACKAGE:用於描述包
  • PARAMETER:用於描述引數
  • TYPE:用於描述類、介面(包括註解型別) 或enum宣告

@Retention定義了該Annotation被保留的時間長短。用於描述註解的生命週期(即:被描述的註解在什麼範圍內有效)取值(RetentionPoicy)有:

    1.SOURCE:在原始檔中有效(即原始檔保留)
    2.CLASS:在class檔案中有效(即class保留)
    3.RUNTIME:在執行時有效(即執行時保留

其餘還有兩個元註解:--我沒用 所以就先不寫啦

@Documented用於描述其它型別的annotation應該被作為被標註的程式成員的公共API

@Inherited 元註解是一個標記註解,@Inherited闡述了某個被標註的型別是被繼承的

2. 註解解析

這裡主要是要解析userid,一個引數。所以其實是通過

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;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor // 這個如果需要初始化的引數可以不用
public class InternalSubjectResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.hasParameterAnnotation(InternalSubject.class); // 檢查需要解析的引數條件,這裡是被使用了該註解的引數
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter,
                                  ModelAndViewContainer modelAndViewContainer,
                                  NativeWebRequest nativeWebRequest,
                                  WebDataBinderFactory webDataBinderFactory) throws Exception {
        return UserIdHolder.getUserId(); // 核心在這裡 返回要解析的引數的的返回值
    }
}

對於引數的解析,其實是在一個地方賦值過了。 

所以其實

public class UserIdHolder {
    private static ThreadLocal<String> tokenThreadLocal = new ThreadLocal<>(); // 通過這個記錄

    public static String getAuthorizedUserId() {
        return tokenThreadLocal.get();
    }

    public static void setAuthorizedUserIdn(String userId) {
        tokenThreadLocal.set(userId); // 可以在filter 或則interceptor中進行set  !! 這是關聯性 
    }

    public static void removeAuthorizedUserId() {
        tokenThreadLocal.remove();
    }

}

備註下 maven

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <optional>true</optional>
</dependency>