在上一篇文章《SpringBoot進階教程(六十四)注解大全》中介紹了springboot的常用注解,springboot提供的注解非常的多,這些注解簡化了我們的很多操作。今天主要介紹介紹自定義注解。
自spring4.0開放以來,自定義注解非常常見,項目中都會或多或少的使用自定義注解,我們的demo中主要針對登錄校驗來介紹如何量身定制自定義注解。
v項目結構
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/
關於作者:專注於基礎平台的項目開發。如有問題或建議,請多多賜教!
版權聲明:本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
特此聲明:所有評論和私信都會在第一時間回復。也歡迎園子的大大們指正錯誤,共同進步。或者直接私信我
聲援博主:如果您覺得文章對您有幫助,可以點擊文章右下角【推薦】一下。您的鼓勵是作者堅持原創和持續寫作的最大動力!