java如何自定義注解
注解是一種能被添加到j(luò)ava源代碼中的元數(shù)據(jù),方法、類(lèi)、參數(shù)和包都可以用注解來(lái)修飾。
注解可以看作是一種特殊的標(biāo)記,可以用在方法、類(lèi)、參數(shù)和包上,程序在編譯或者運(yùn)行時(shí)可以檢測(cè)到這些標(biāo)記而進(jìn)行一些特殊的處理。
聲明一個(gè)注解要用到的東西
- 修飾符:訪(fǎng)問(wèn)修飾符必須為public,不寫(xiě)默認(rèn)為pubic
- 關(guān)鍵字:關(guān)鍵字為@interface
- 注解名稱(chēng):注解名稱(chēng)為自定義注解的名稱(chēng),使用時(shí)還會(huì)用到
- 注解類(lèi)型元素:注解類(lèi)型元素是注解中內(nèi)容
其次,JDK中還有一些元注解,這些元注解可以用來(lái)修飾注解。
主要有:@Target,@Retention,@Document,@Inherited。
@Target
作用:
用于描述注解的使用范圍(即:被描述的注解可以用在什么地方)。
取值有:
@Retention
作用:
表示需要在什么級(jí)別保存該注釋信息,用于描述注解的生命周期(即:被描述的注解在什么范圍內(nèi)有效)
即:注解的生命周期。
@Document
作用:
表明該注解標(biāo)記的元素可以被Javadoc 或類(lèi)似的工具文檔化
@Inherited
作用:
表明使用了@Inherited注解的注解,所標(biāo)記的類(lèi)的子類(lèi)也會(huì)擁有這個(gè)注解。
自定義注解中參數(shù)可支持的數(shù)據(jù)類(lèi)型:
1.八大基本數(shù)據(jù)類(lèi)型
2.String類(lèi)型
3.Class類(lèi)型
4.enum類(lèi)型
5.Annotation類(lèi)型
6.以上所有類(lèi)型的數(shù)組
自定義一個(gè)注解,如下所示:
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface OperationLog { String username() default ""; OperationType type(); String content() default ""; }
通過(guò)AOP加自定義注解簡(jiǎn)單實(shí)現(xiàn)一個(gè)操作日志的記錄
自定義注解類(lèi):
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(); //記錄操作類(lèi)型 String content() default ""; //記錄操作內(nèi)容 }
切面類(lè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); } /** * 攔截異常操作,有異常時(shí)執(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; } // 得到方法名稱(chēng) 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("操作類(lèi)型:" + type); System.out.println("操作名稱(chēng):" + content); System.out.println("操作人員:" + username); System.out.println("類(lèi)名:" + 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; } }
測(cè)試類(lèi):
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)用測(cè)試類(lèi)各個(gè)接口,記錄的操作日志信息如下:
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot實(shí)現(xiàn)郵件發(fā)送功能的姿勢(shì)分享
我們?cè)谌粘i_(kāi)發(fā)中,經(jīng)常會(huì)碰到email郵件發(fā)送的場(chǎng)景,如發(fā)送驗(yàn)證碼,向客戶(hù)發(fā)送郵件等等,這篇文章主要給大家介紹了關(guān)于SpringBoot實(shí)現(xiàn)郵件發(fā)送的相關(guān)資料,需要的朋友可以參考下2021-08-08easyexcel讀取excel合并單元格數(shù)據(jù)的操作代碼
這篇文章主要介紹了easyexcel讀取excel合并單元格數(shù)據(jù)的操作代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05淺談SpringCloud的微服務(wù)架構(gòu)組件
這篇文章主要介紹了淺談SpringCloud的微服務(wù)架構(gòu)組件,Spring Cloud根據(jù)分布式服務(wù)協(xié)調(diào)治理的需求成立了許多子項(xiàng)目,每個(gè)項(xiàng)目通過(guò)特定的組件去實(shí)現(xiàn),需要的朋友可以參考下2023-04-04關(guān)于json解析多層嵌套并轉(zhuǎn)為對(duì)應(yīng)類(lèi)(List)
在進(jìn)行JSON解析時(shí),遇到多層嵌套結(jié)構(gòu)可通過(guò)遞歸或?qū)S脦?kù)來(lái)實(shí)現(xiàn),重要的是將嵌套的JSON對(duì)象準(zhǔn)確轉(zhuǎn)化為對(duì)應(yīng)的Java類(lèi),通常需要依賴(lài)如Gson或Jackson等庫(kù),將JSONObject轉(zhuǎn)為JavaBean時(shí),關(guān)注字段匹配與數(shù)據(jù)類(lèi)型轉(zhuǎn)換2024-10-10通過(guò)FeignClient調(diào)用微服務(wù)提供的分頁(yè)對(duì)象IPage報(bào)錯(cuò)的解決
這篇文章主要介紹了通過(guò)FeignClient調(diào)用微服務(wù)提供的分頁(yè)對(duì)象IPage報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03