自定義注解
注解是什么?
注解(Annotation)也叫元數(shù)據(jù),用于對代碼進行說明,可以對包、類、接口、字段、方法參數(shù)、局部變量等進行注解。其實說白就是代碼里的特殊標志,這些標志可以在編譯,類加載,運行時被讀取,并根據(jù)這些信息執(zhí)行相應(yīng)的處理,以便于其他工具補充信息或者進行部署。
元數(shù)據(jù)(Metadata),又稱中介數(shù)據(jù)、中繼數(shù)據(jù),為描述數(shù)據(jù)的數(shù)據(jù)(data about data),主要是描述數(shù)據(jù)屬性(property)的信息,用來支持如指示存儲位置、歷史數(shù)據(jù)、資源查找、文件記錄等功能。
如果說注釋是寫給人看的,那么注解就是寫給程序看的。它更像一個標簽,貼在一個類、一個方法或者字段上。它的目的是為當前讀取該注解的程序提供判斷依據(jù)。比如程序只要讀到加了@Test的方法,就知道該方法是待測試方法,又比如@Before注解,程序看到這個注解,就知道該方法要放在@Test方法之前執(zhí)行。
注解類型
@Target(標明注解使用的范圍)
“@Target(ElementType.TYPE):作用接口、類、枚舉、注解 @Target(ElementType.FIELD) :作用屬性字段、枚舉的常量 @Target(ElementType.METHOD):作用方法 @Target(ElementType.PARAMETER):作用方法參數(shù)
”
@Retention(標明注解被保留的階段)
“@Retention(RetentionPolicy.SOURCE) 注解僅存在于源碼中,在class字節(jié)碼文件中不包含 @Retention(RetentionPolicy.CLASS) 默認的策略,在class字節(jié)碼文件中存在,但運行時無法獲得 @Retention(RetentionPolicy.RUNTIME) 在class字節(jié)碼文件中存在,在運行時可以通過反射獲取到
”
@Documented(標明是否生成javadoc文檔)
@Inherited(標明注解可繼承)
舉個栗子
創(chuàng)建注解
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SysLog {
//模塊
String model();
//方法名稱
String name();
//功能code
String[] code();
}
AOP處理注解
@Component
@Aspect
@Slf4j
public class SysLogAspect {
@Pointcut("@annotation(com.example.demo.annotation.SysLog)")
public void logPoint(){}
@Around("logPoint()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable{
Object result = null;
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null){
SysLog sysLog = method.getAnnotation(SysLog.class);
String[] code = sysLog.code();
String name = sysLog.name();
String model = sysLog.model();
Object proceed = joinPoint.proceed();
log.info("code = {},name={},model={},proceed={}",code,name,model,proceed);
return proceed;
}
return result;
}
}
使用注解
@RestController
public class UserController {
@SysLog(model = "用戶模塊", name = "getUserName", code = {"c","r","u","d"})
@GetMapping("/userName")
public void getUserName(String userName){
return userName;
}
}
AOP中l(wèi)og日志打印結(jié)果
“code = [c, r, u, d],name=getUserName,model=用戶模塊,proceed=liugui
”
