最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JAVA自定義注解使用指南

 更新時間:2025年11月15日 08:49:38   作者:syf0824  
注解是一種特殊的接口,用于為Java代碼提供元數(shù)據(jù),它們不會直接影響代碼的執(zhí)行,但可以被編譯器、開發(fā)工具或運(yùn)行時環(huán)境讀取和使用,本文給大家介紹JAVA自定義注解的相關(guān)知識,感興趣的朋友一起看看吧

什么是注解?

注解是一種特殊的接口,用于為Java代碼提供元數(shù)據(jù)。它們不會直接影響代碼的執(zhí)行,但可以被編譯器、開發(fā)工具或運(yùn)行時環(huán)境讀取和使用。

Java內(nèi)置了一些常用的注解,如:

@Override - 表示方法重寫父類方法

@Deprecated - 表示代碼已過時

@SuppressWarnings - 抑制編譯器警告

注解的基本語法

定義注解

使用@interface關(guān)鍵字來定義注解:

public @interface AutoFill {
}

元注解

元注解是用來注解其他注解的注解,Java提供了以下幾種元注解:

@Target - 指定注解可以應(yīng)用的目標(biāo)元素類型

@Retention - 指定注解的保留策略

@Documented - 表示注解應(yīng)該被包含在Javadoc中

@Inherited - 表示注解可以被繼承

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
    /**
     * 數(shù)據(jù)庫操作類型:INSERT、UPDATE
     */
    OperationType value();
}

示例代碼展示了一個用于公共字段自動填充的自定義注解,@Target明確注解可在方法上使用,@Retention明確在程序運(yùn)行時可見。

注解元素

注解中可以定義元素,這些元素可以有默認(rèn)值:

public enum OperationType {
    /**
     * 更新操作
     */
    UPDATE,
    /**
     * 插入操作
     */
    INSERT
}

示例自定義注解中的value方法則用來返回上示枚舉類型數(shù)據(jù),明確 使用該注解的方法 的作用,使用方式如下:

/**
      * 更新員工信息
      * @param employee
      */
     @AutoFill(OperationType.UPDATE) 
     void updateById(Employee employee);

當(dāng)注解只有一個方法且方法名為 value 時,使用時可以省略方法名,如果方法不叫 value,就必須明確指定方法名:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
    /**
     * 數(shù)據(jù)庫操作類型:INSERT、UPDATE
     */
    OperationType type();
}
/**
      * 更新員工信息
      * @param employee
      */
     @AutoFill(type = OperationType.UPDATE) 
     void updateById(Employee employee);

自定義注解的使用

通過反射處理注解

我們可以使用反射機(jī)制在運(yùn)行時讀取和處理注解:

@Aspect
@Component
@Slf4j
public class AutoFillAspect {
    /**
     * 公共字段自動填充切入點(diǎn)
     */
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut() {}
    /**
     * 公共字段自動填充
     */
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint) throws Throwable {
        log.info("公共字段自動填充通知開始");
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        AutoFill autoFill= signature.getMethod().getAnnotation(AutoFill.class);
        // 獲取數(shù)據(jù)庫操作類型
        Enum operationType = autoFill.value();
        // 從ThreadLocal中獲取當(dāng)前登錄用戶的id
        Long currentId = BaseContext.getCurrentId();
        // 獲取當(dāng)前時間
        LocalDateTime now = LocalDateTime.now();
        // 從joinPoint中獲取參數(shù)
        Object[] args = joinPoint.getArgs();
        if(args==null || args.length==0){
            return;
        }
        // 從參數(shù)中獲取實(shí)體對象
        Object entity = args[0];
        // 調(diào)用實(shí)體對象的方法,設(shè)置創(chuàng)建時間、創(chuàng)建人、更新時間、更新人
        if(operationType==OperationType.INSERT){
            try{
                Method setCreateTime = entity.getClass().getDeclaredMethod("setCreateTime", LocalDateTime.class);
                Method setUpdateTime = entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
                Method setCreateUser = entity.getClass().getDeclaredMethod("setCreateUser", Long.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod("setUpdateUser", Long.class);
                setCreateTime.invoke(entity, now);
                setUpdateTime.invoke(entity, now);
                setCreateUser.invoke(entity, currentId);
                setUpdateUser.invoke(entity, currentId);
            }catch (Exception e){
                log.error("公共字段自動填充通知異常", e);
            }
        }else if(operationType==OperationType.UPDATE){
            try{
                Method setUpdateTime = entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod("setUpdateUser", Long.class);
                setUpdateTime.invoke(entity, now);
                setUpdateUser.invoke(entity, currentId);
            }catch (Exception e){
                log.error("公共字段自動填充通知異常", e);
            }
        }
    }
}

上述示例展示的是@AutoFill注解進(jìn)行公共字段自動填充必要的切面類。

@Aspect

該注解用于聲明切面類。

/**
     * 公共字段自動填充切入點(diǎn)
     */
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut() {}

這一部分用于聲明哪些部分需要攔截。(在com.sky.mapper包下的所有類及其所有方法  被自定義注解(@AutoFill)所標(biāo)注)

/**
     * 公共字段自動填充
     */
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint) throws Throwable

@Before: 表示這是一個前置通知,在目標(biāo)方法執(zhí)行之前運(yùn)行。

autoFillPointCut(): 引用一個切點(diǎn)表達(dá)式,定義了哪些方法需要被攔截。

JoinPoint: AOP 連接點(diǎn)對象,可以獲取被攔截方法的詳細(xì)信息:方法名、參數(shù)、目標(biāo)對象等。通過 joinPoint.getArgs() 獲取方法參數(shù)。

MethodSignature signature = (MethodSignature)joinPoint.getSignature();
AutoFill autoFill= signature.getMethod().getAnnotation(AutoFill.class);
// 獲取數(shù)據(jù)庫操作類型
Enum operationType = autoFill.value();

joinPoint.getSignature(): 獲取連接點(diǎn)的簽名信息。

(MethodSignature): 強(qiáng)制轉(zhuǎn)換為 MethodSignature 類型,因?yàn)?nbsp;Spring AOP 只攔截方法。

signature.getMethod(): 獲取被攔截的 Method 對象。

.getAnnotation(AutoFill.class): 從方法上獲取 @AutoFill 注解。

autoFill.value(): 調(diào)用注解的 value() 方法,獲取注解中定義的枚舉值。

// 從joinPoint中獲取參數(shù)
        Object[] args = joinPoint.getArgs();
        if(args==null || args.length==0){
            return;
        }
        // 從參數(shù)中獲取實(shí)體對象
        Object entity = args[0];

利用從joinPoint中獲取的參數(shù)獲得原本方法中傳遞的實(shí)體對象。

Method setCreateTime = entity.getClass().getDeclaredMethod("setCreateTime", LocalDateTime.class);
Method setCreateUser = entity.getClass().getDeclaredMethod("setCreateUser", Long.class);
setCreateTime.invoke(entity, now);
setCreateUser.invoke(entity, currentId);

利用反射為對象設(shè)置公共字段。

最終效果

@AutoFill注解能有效替代原本冗長且重復(fù)的公共字段設(shè)置代碼。

到此這篇關(guān)于JAVA自定義注解全解的文章就介紹到這了,更多相關(guān)java自定義注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java sm3加密算法的實(shí)現(xiàn)

    Java sm3加密算法的實(shí)現(xiàn)

    這篇文章主要介紹了Java sm3加密算法的實(shí)現(xiàn),幫助大家更好的利用Java進(jìn)行加密,感興趣的朋友可以了解下
    2020-10-10
  • JDK8?中Arrays.sort()?排序方法詳解

    JDK8?中Arrays.sort()?排序方法詳解

    這篇文章主要介紹了JDK8?中Arrays.sort()?排序方法解讀,本文先行介紹Arrays.sort()中影響排序方式的幾個因素,影響因素主要為數(shù)組類型、數(shù)組大小,結(jié)合閾值對排序方式進(jìn)行選擇,需要的朋友可以參考下
    2023-05-05
  • SpringBoot項(xiàng)目打包發(fā)布到外部tomcat(出現(xiàn)各種異常的解決)

    SpringBoot項(xiàng)目打包發(fā)布到外部tomcat(出現(xiàn)各種異常的解決)

    這篇文章主要介紹了SpringBoot項(xiàng)目打包發(fā)布到外部tomcat(出現(xiàn)各種異常的解決),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 基于Quartz定時調(diào)度任務(wù)(詳解)

    基于Quartz定時調(diào)度任務(wù)(詳解)

    下面小編就為大家?guī)硪黄赒uartz定時調(diào)度任務(wù)(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • 解決RocketMQ的冪等性問題

    解決RocketMQ的冪等性問題

    重復(fù)消費(fèi)因調(diào)用鏈路長、消息發(fā)送超時或消費(fèi)者故障導(dǎo)致,通過生產(chǎn)者消息查詢、Redis緩存及消費(fèi)者唯一主鍵可以確保冪等性,避免重復(fù)處理,本文主要介紹了解決RocketMQ的冪等性問題,感興趣的可以了解一下
    2025-07-07
  • 使用Java凍結(jié)Excel行和列的完整指南

    使用Java凍結(jié)Excel行和列的完整指南

    在日常數(shù)據(jù)處理和報表生成中,Excel 扮演著不可或缺的角色,然而,當(dāng)面對包含成百上千行、幾十乃至上百列的大型 Excel 文件時,反復(fù)滾動查看數(shù)據(jù)往往會帶來極大的不便,所以本文旨在提供一份清晰、實(shí)用且基于 Java 的解決方案,幫助讀者高效地實(shí)現(xiàn) Excel 行和列的凍結(jié)操作
    2026-02-02
  • spring Security配置攔截規(guī)則小結(jié)

    spring Security配置攔截規(guī)則小結(jié)

    本文介紹了使用Spring Security解決后臺管理系統(tǒng)在訪問靜態(tài)資源如圖片時需要登錄驗(yàn)證的問題,通過配置攔截規(guī)則,將靜態(tài)資源路徑添加到白名單,感興趣的可以了解一下
    2025-09-09
  • Java實(shí)現(xiàn)abc字符串排列組合

    Java實(shí)現(xiàn)abc字符串排列組合

    這篇文章主要為大家詳細(xì)介紹了JAVA實(shí)現(xiàn)abc字符串的排列組合,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • Springboot整合RabbitMq測試TTL的方法詳解

    Springboot整合RabbitMq測試TTL的方法詳解

    這篇文章主要介紹了Springboot整合RabbitMq測試TTL的設(shè)置,設(shè)置TTL一般由兩種設(shè)置方法,設(shè)置整個隊列的過期時間另一種設(shè)置單個消息的過期時間,通過示例圖文相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-03-03
  • JAVA 并發(fā)容器的一些易出錯點(diǎn)你知道嗎

    JAVA 并發(fā)容器的一些易出錯點(diǎn)你知道嗎

    今天給大家?guī)淼奈恼率荍ava并發(fā)編程的相關(guān)知識,文中對java同步容器與并發(fā)容器做了非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-09-09

最新評論

永城市| 肥西县| 无棣县| 交口县| 平武县| 孙吴县| 蒙山县| 恭城| 石狮市| 长宁县| 平凉市| 昌江| 沙坪坝区| 黔东| 霍州市| 永寿县| 喀什市| 裕民县| 镇巴县| 玉山县| 东山县| 杨浦区| 包头市| 平昌县| 宜城市| 枞阳县| 巴彦淖尔市| 巩留县| 安康市| 方正县| 龙胜| 老河口市| 周宁县| 阿克| 沙雅县| 汾阳市| 黄冈市| 滨海县| 宁晋县| 盐津县| 胶州市|