SpringBoot進階教程(六十五)自定義註解

在上一篇文章《SpringBoot進階教程(六十四)註解大全》中介紹了springboot的常用註解,springboot提供的註解非常的多,這些註解簡化了我們的很多操作。今天主要介紹介紹自定義註解。

自spring4.0開放以來,自定義註解非常常見,項目中都會或多或少的使用自定義註解,我們的demo中主要針對登錄校驗來介紹如何量身定製自定義註解。

v項目結構

SpringBoot進階教程(六十四)自定義註解

v定義註解

package learn.web.controller.interceptor;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * @author toutou
 * @date by 2020/11
 * @des
 */
@Documented
@Retention(RUNTIME)
@Target(METHOD)
public @interface Login {
}

元註解釋義:

java.lang.annotation提供了四種元註解,專門註解其他的註解(在自定義註解的時候,需要使用到元註解):

@Documented:註解是否將包含在JavaDoc中

@Retention:什麼時候使用該註解,指明修飾的註解的生存週期,即會保留到哪個階段。

1.RetentionPolicy.SOURCE —— 這種類型的Annotations只在源代碼級別保留,編譯時就會被忽略
2.RetentionPolicy.CLASS —— 這種類型的Annotations編譯時被保留,在class文件中存在,但JVM將會忽略
3.RetentionPolicy.RUNTIME —— 這種類型的Annotations將被JVM保留,所以他們能在運行時被JVM或其他使用反射機制的代碼所讀取和使用

@Target:註解用於什麼地方,指明瞭修飾的這個註解的使用範圍,即被描述的註解可以用在哪裏。

1.TYPE——用於描述類、接口(包括註解類型) 或enum聲明
2.FIELD——用於字段聲明(包括枚舉常量)
3.METHOD——用於方法聲明
4.PARAMETER——用於參數聲明
5.CONSTRUCTOR——用於構造函數聲明
6.LOCAL_VARIABLE——用於本地變量聲明
7.ANNOTATION_TYPE——用於註解類型聲明
8.PACKAGE——用於包聲明
9.TYPE_PARAMETER—— 用於類型參數聲明,JavaSE8引進,可以應用於類的泛型聲明之處
10.TYPE_USE——JavaSE8引進,此類型包括類型聲明和類型參數聲明,是爲了方便設計者進行類型檢查,例如,如果使用@Target(ElementType.TYPE_USE)對@NonNull進行標記,則類型檢查器可以將@NonNull class C {...} C類的所有變量都視爲非null

@Inherited:是否允許子類繼承該註解

v實現註解

 

/**
 * @author toutou
 * @date by 2020/11
 * @des
 */
@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("Interceptor Interceptor Interceptor Interceptor Interceptor Interceptor Interceptor");
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            Login login = method.getAnnotation(Login.class);
            if(login!=null) {
                // login!=null表示@Login註解生效
                if(!"user".equals(request.getParameter("user"))){
                    new RuntimeException("沒有登錄.");
                }
            }
        }

        return true;
    }
}

v配置攔截器

package learn.web.controller.config;

import learn.web.controller.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

/**
 * @author toutou
 * @date by 2020/11
 * @des
 */
@Configuration
public class WebMvcConfig extends DelegatingWebMvcConfiguration {
    @Autowired
    LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor);
        super.addInterceptors(registry);
        System.out.println("Interceptor Interceptor Interceptor Interceptor Interceptor Interceptor Interceptor");
    }
}

v使用註解

@RestController
public class UserController {
    @GetMapping("/user/hello")
    @Login
    public String helloWorld() {
        return "hello world.";
    }
}

v源碼地址

https://github.com/toutouge/javademosecond/tree/master/hellolearn

v博客總結

寫到這才發現,項目結構目錄有點小問題,interceptor和config兩個包應該是和controller平行的,而不是controller的子目錄。即:package learn.web.controller.interceptor改成package learn.web.interceptor;learn.web.controller.config改成learn.web.config。原文就懶得重新捯飭了,大家注意下就行,當然原文也不會有問題,只是目錄結構改一下會更好。


作  者:請叫我頭頭哥
出  處:http://www.cnblogs.com/toutou/
關於作者:專注於基礎平臺的項目開發。如有問題或建議,請多多賜教!
版權聲明:本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
特此聲明:所有評論和私信都會在第一時間回覆。也歡迎園子的大大們指正錯誤,共同進步。或者直接私信
聲援博主:如果您覺得文章對您有幫助,可以點擊文章右下角推薦一下。您的鼓勵是作者堅持原創和持續寫作的最大動力!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章