javascript
@retention注解作用_分分钟带你玩转SpringBoot自定义注解
在工作中,我們有時候需要將一些公共的功能封裝,比如操作日志的存儲,防重復提交等等。這些功能有些接口會用到,為了便于其他接口和方法的使用,做成自定義注解,侵入性更低一點。別人用的話直接注解就好。下面就來講講自定義注解這些事情。
一.@Target、@Retention、@Documented簡介
java自定義注解的注解位于表:java.lang.annotation下。包含三個元注解@Target、@Retention、@Documented,即注解的注解。
@Target
@Target:注解的作用目標。和枚舉ElementType共同起作用
根據(jù)源碼知道,可以配置多個作用目標。
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target {/*** Returns an array of the kinds of elements an annotation type* can be applied to.* @return an array of the kinds of elements an annotation type* can be applied to*/ElementType[] value(); } 復制代碼ElementType的類型如下:
* @author Joshua Bloch* @since 1.5* @jls 9.6.4.1 @Target* @jls 4.1 The Kinds of Types and Values*/ public enum ElementType {/** 類, 接口 (包括注解類型), 或 枚舉 聲明 */TYPE,/** 字段聲明(包括枚舉常量) */FIELD,/** 方法聲明(Method declaration) */METHOD,/** 正式的參數(shù)聲明 */PARAMETER,/** 構(gòu)造函數(shù)聲明 */CONSTRUCTOR,/** 局部變量聲明 */LOCAL_VARIABLE,/** 注解類型聲明 */ANNOTATION_TYPE,/** 包聲明 */PACKAGE,/*** 類型參數(shù)聲明** @since 1.8*/TYPE_PARAMETER,/*** 使用的類型** @since 1.8*/TYPE_USE } 復制代碼@Retention
指示帶注解類型的注解要多長時間被保留。如果沒有保留注釋存在 注釋類型聲明,保留策略默認為 {@code RetentionPolicy.CLASS}和RetentionPolicy共同起作用。
RetentionPolicy類型如下:
package java.lang.annotation;/*** Annotation retention policy. The constants of this enumerated type* describe the various policies for retaining annotations. They are used* in conjunction with the {@link Retention} meta-annotation type to specify* how long annotations are to be retained.** @author Joshua Bloch* @since 1.5*/ public enum RetentionPolicy {/*** 注解只保留在源文件,當Java文件編譯成class文件的時候,注解被遺棄;被編譯器忽略*/SOURCE,/*** 注解被保留到class文件,但jvm加載class文件時候被遺棄,這是默認的生命周期*/CLASS,/*** 注解不僅被保存到class文件中,jvm加載class文件之后,仍然存在*/RUNTIME }復制代碼這3個生命周期分別對應于:Java源文件(.java文件) ---> .class文件 ---> 內(nèi)存中的字節(jié)碼。
那怎么來選擇合適的注解生命周期呢?首先要明確生命周期長度 SOURCE < CLASS < RUNTIME ,所以前者能作用的地方后者一定也能作用。一般如果需要在運行時去動態(tài)獲取注解信息,那只能用 RUNTIME 注解;如果要在編譯時進行一些預處理操作,比如生成一些輔助代碼(如 ButterKnife),就用 CLASS注解;如果只是做一些檢查性的操作,比如 @Override 和 @SuppressWarnings,則可選用 SOURCE 注解。
**@**Documented
**@**Documented 注解表明這個注解應該被 javadoc工具記錄. 默認情況下,javadoc是不包括注解的. 但如果聲明注解時指定了 @Documented,則它會被 javadoc 之類的工具處理, 所以注解類型信息也會被包括在生成的文檔中,是一個標記注解,沒有成員。
二.編寫自定義注解
1.創(chuàng)建自定annotation包
當然,名字自定義
2.創(chuàng)建自定義注解
我這里以Log為例。這里是通過新建自定義注解創(chuàng)建的。也可以手動創(chuàng)建一個class類進行修改@interface呢。
public @interface test { } 復制代碼3.加入元注解
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Log {String value() default ""; } 復制代碼4.編寫AOP
@Aspect @Component public class SysLogAspect {/*** logger*/private static final Logger LOGGER = LoggerFactory.getLogger(SysLogAspect.class);@Pointcut("@annotation(com.aldeo.common.annotation.Log)")public void logPointCut() {}@Around("logPointCut()")public Object around(ProceedingJoinPoint point) throws Throwable {long beginTime = System.currentTimeMillis();// 目標方法Object result = point.proceed();long time = System.currentTimeMillis() - beginTime;Log syslog = method.getAnnotation(Log.class);if (syslog != null) {// 注解上的描述LOGGER.info(syslog.value());}// 保存日志try {saveLog(point, time);} catch (Exception e) {LOGGER.error("==================================> saveSysLog.around.exception: " + e.getMessage(), e);}return result;} 復制代碼三.使用
在需要注解的方法上加上注解
@Log("測試自定義注解") public String restPassword(){return "成功"; } 復制代碼運行結(jié)果
2020-11-14 16:09:00.245 |-INFO http-nio-6089-exec-9 c.v.t.*.40 - gmzakixAkym3 : 測試自定義注解 復制代碼四.自定義注解使用場景和原理
自定義注解的原理,就是自己定義完注解。將注解加到需要注解的方法上。然后在攔截器攔截到注解的,然后進行后續(xù)的處理。
登陸、權(quán)限攔截、日志處理,以及各種 Java 框架,如 Spring,Hibernate,JUnit 提到注解就不能不說反射,Java 自定義注解是通過運行時靠反射獲取注解。實際開發(fā)中,例如我們要獲取某個方法的調(diào)用日志,可以通過 AOP(動態(tài)代理機制)給方法添加切面,通過反射來獲取方法包含的注解,如果包含日志注解,就進行日志記錄。反射地實現(xiàn)在 Java 應用層面上講,是通過對 Class 對象的操作實現(xiàn)的,Class 對象為我們提供了一系列方法對類進行操作。在 JVM 這個角度來說,Class 文件是一組以 8 位字節(jié)為基礎單位的二進制流,各個數(shù)據(jù)項目按嚴格的順序緊湊地排列在 Class 文件中,里面包含了類、方法、字段等等相關(guān)數(shù)據(jù)。通過對 Class 數(shù)據(jù)流的處理我們即可得到字段、方法等數(shù)據(jù)。
原文鏈接:分分鐘玩轉(zhuǎn)SpringBoot自定義注解
總結(jié)
以上是生活随笔為你收集整理的@retention注解作用_分分钟带你玩转SpringBoot自定义注解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: anaconda打不开没反应_为什么账户
- 下一篇: c++输出小数点后几位_2.1 怎么在屏