java如何自定義注解
注解是一種能被添加到j(luò)ava源代碼中的元數(shù)據(jù),方法、類、參數(shù)和包都可以用注解來修飾。
注解可以看作是一種特殊的標(biāo)記,可以用在方法、類、參數(shù)和包上,程序在編譯或者運(yùn)行時可以檢測到這些標(biāo)記而進(jìn)行一些特殊的處理。
聲明一個注解要用到的東西
- 修飾符:訪問修飾符必須為public,不寫默認(rèn)為pubic
- 關(guān)鍵字:關(guān)鍵字為@interface
- 注解名稱:注解名稱為自定義注解的名稱,使用時還會用到
- 注解類型元素:注解類型元素是注解中內(nèi)容
其次,JDK中還有一些元注解,這些元注解可以用來修飾注解。
主要有:@Target,@Retention,@Document,@Inherited。
@Target
作用:
用于描述注解的使用范圍(即:被描述的注解可以用在什么地方)。
取值有:
@Retention
作用:
表示需要在什么級別保存該注釋信息,用于描述注解的生命周期(即:被描述的注解在什么范圍內(nèi)有效)
即:注解的生命周期。
@Document
作用:
表明該注解標(biāo)記的元素可以被Javadoc 或類似的工具文檔化
@Inherited
作用:
表明使用了@Inherited注解的注解,所標(biāo)記的類的子類也會擁有這個注解。
自定義注解中參數(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加自定義注解簡單實(shí)現(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 { // 配置織入點(diǎn) @Pointcut("@annotation(OperationLog)") public void logPointCut() { } /** * 前置通知 用于攔截操作,在方法返回后執(zhí)行 * * @param joinPoint 切點(diǎn) */ @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)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot實(shí)現(xiàn)郵件發(fā)送功能的姿勢分享
我們在日常開發(fā)中,經(jīng)常會碰到email郵件發(fā)送的場景,如發(fā)送驗(yàn)證碼,向客戶發(fā)送郵件等等,這篇文章主要給大家介紹了關(guān)于SpringBoot實(shí)現(xiàn)郵件發(fā)送的相關(guān)資料,需要的朋友可以參考下2021-08-08easyexcel讀取excel合并單元格數(shù)據(jù)的操作代碼
這篇文章主要介紹了easyexcel讀取excel合并單元格數(shù)據(jù)的操作代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-05-05淺談SpringCloud的微服務(wù)架構(gòu)組件
這篇文章主要介紹了淺談SpringCloud的微服務(wù)架構(gòu)組件,Spring Cloud根據(jù)分布式服務(wù)協(xié)調(diào)治理的需求成立了許多子項(xiàng)目,每個項(xiàng)目通過特定的組件去實(shí)現(xiàn),需要的朋友可以參考下2023-04-04關(guān)于json解析多層嵌套并轉(zhuǎn)為對應(yīng)類(List)
在進(jìn)行JSON解析時,遇到多層嵌套結(jié)構(gòu)可通過遞歸或?qū)S脦靵韺?shí)現(xiàn),重要的是將嵌套的JSON對象準(zhǔn)確轉(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