java如何自定義注解
注解是一種能被添加到j(luò)ava源代碼中的元數(shù)據(jù),方法、類、參數(shù)和包都可以用注解來修飾。
注解可以看作是一種特殊的標記,可以用在方法、類、參數(shù)和包上,程序在編譯或者運行時可以檢測到這些標記而進行一些特殊的處理。
聲明一個注解要用到的東西
- 修飾符:訪問修飾符必須為public,不寫默認為pubic
- 關(guān)鍵字:關(guān)鍵字為@interface
- 注解名稱:注解名稱為自定義注解的名稱,使用時還會用到
- 注解類型元素:注解類型元素是注解中內(nèi)容
其次,JDK中還有一些元注解,這些元注解可以用來修飾注解。
主要有:@Target,@Retention,@Document,@Inherited。
@Target
作用:
用于描述注解的使用范圍(即:被描述的注解可以用在什么地方)。
取值有:

@Retention
作用:
表示需要在什么級別保存該注釋信息,用于描述注解的生命周期(即:被描述的注解在什么范圍內(nèi)有效)
即:注解的生命周期。

@Document
作用:
表明該注解標記的元素可以被Javadoc 或類似的工具文檔化
@Inherited
作用:
表明使用了@Inherited注解的注解,所標記的類的子類也會擁有這個注解。
自定義注解中參數(shù)可支持的數(shù)據(jù)類型:
1.八大基本數(shù)據(jù)類型
2.String類型
3.Class類型
4.enum類型
5.Annotation類型
6.以上所有類型的數(shù)組
自定義一個注解,如下所示:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLog {
String username() default "";
OperationType type();
String content() default "";
}通過AOP加自定義注解簡單實現(xiàn)一個操作日志的記錄
自定義注解類:
package com.redistext.log;
import java.lang.annotation.*;
/**
* @author: maorui
* @description: TODO
* @date: 2021/10/27 21:23
* @description: V1.0
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLog {
String username() default "admin";
String type(); //記錄操作類型
String content() default ""; //記錄操作內(nèi)容
}切面類:
package com.redistext.log;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* @author: maorui
* @description: TODO
* @date: 2021/10/27 21:29
* @description: V1.0
*/
@Aspect
@Component("logAspect")
public class LogAspect {
// 配置織入點
@Pointcut("@annotation(OperationLog)")
public void logPointCut() {
}
/**
* 前置通知 用于攔截操作,在方法返回后執(zhí)行
*
* @param joinPoint 切點
*/
@AfterReturning(pointcut = "logPointCut()")
public void doBefore(JoinPoint joinPoint) {
handleLog(joinPoint, null);
}
/**
* 攔截異常操作,有異常時執(zhí)行
*
* @param joinPoint
* @param e
*/
@AfterThrowing(value = "logPointCut()", throwing = "e")
public void doAfter(JoinPoint joinPoint, Exception e) {
handleLog(joinPoint, e);
}
private void handleLog(JoinPoint joinPoint, Exception e){
try {
// 得到注解
OperationLog operationLog = getAnnotationLog(joinPoint);
System.out.println("---------------自定義注解:" + operationLog);
if (operationLog == null) {
return;
}
// 得到方法名稱
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
String type = operationLog.type();
String content = operationLog.content();
String username = operationLog.username();
// 打印日志
System.out.println("操作類型:" + type);
System.out.println("操作名稱:" + content);
System.out.println("操作人員:" + username);
System.out.println("類名:" + className);
System.out.println("方法名:" + methodName);
} catch (Exception e1) {
System.out.println("======前置通知異常======");
e1.printStackTrace();
}
}
private static OperationLog getAnnotationLog(JoinPoint joinPoint) throws Exception{
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null) {
// 拿到自定義注解中的信息
return method.getAnnotation(OperationLog.class);
}
return null;
}
}測試類:
package com.redistext.log;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author: maorui
* @description: TODO
* @date: 2021/10/27 21:40
* @description: V1.0
*/
@RestController
@RequestMapping("/operationLog")
public class OperationLogController {
@OperationLog(type = "add", content = "添加")
@GetMapping(value = "/add")
public String addOperation(){
return "add";
}
@OperationLog(type = "update", username = "adminFather")
@GetMapping(value = "/update")
public String updateOperation(){
return "update";
}
@OperationLog(type = "delete", content = "刪除", username = "adminMother")
@GetMapping(value = "/delete")
public String deleteOperation(){
return "delete";
}
@OperationLog(type = "find")
@GetMapping(value = "/find")
public String findOperation(){
return "find";
}
}依次調(diào)用測試類各個接口,記錄的操作日志信息如下:

總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot實現(xiàn)郵件發(fā)送功能的姿勢分享
我們在日常開發(fā)中,經(jīng)常會碰到email郵件發(fā)送的場景,如發(fā)送驗證碼,向客戶發(fā)送郵件等等,這篇文章主要給大家介紹了關(guān)于SpringBoot實現(xiàn)郵件發(fā)送的相關(guān)資料,需要的朋友可以參考下2021-08-08
easyexcel讀取excel合并單元格數(shù)據(jù)的操作代碼
這篇文章主要介紹了easyexcel讀取excel合并單元格數(shù)據(jù)的操作代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-05-05
淺談SpringCloud的微服務(wù)架構(gòu)組件
這篇文章主要介紹了淺談SpringCloud的微服務(wù)架構(gòu)組件,Spring Cloud根據(jù)分布式服務(wù)協(xié)調(diào)治理的需求成立了許多子項目,每個項目通過特定的組件去實現(xiàn),需要的朋友可以參考下2023-04-04
關(guān)于json解析多層嵌套并轉(zhuǎn)為對應(yīng)類(List)
在進行JSON解析時,遇到多層嵌套結(jié)構(gòu)可通過遞歸或?qū)S脦靵韺崿F(xiàn),重要的是將嵌套的JSON對象準確轉(zhuǎn)化為對應(yīng)的Java類,通常需要依賴如Gson或Jackson等庫,將JSONObject轉(zhuǎn)為JavaBean時,關(guān)注字段匹配與數(shù)據(jù)類型轉(zhuǎn)換2024-10-10
通過FeignClient調(diào)用微服務(wù)提供的分頁對象IPage報錯的解決
這篇文章主要介紹了通過FeignClient調(diào)用微服務(wù)提供的分頁對象IPage報錯的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03

