1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        俯拾皆是的Java注解,你真的get了嗎?

        共 6226字,需瀏覽 13分鐘

         ·

        2023-10-17 06:42


        歡迎關(guān)注微信公眾號:互聯(lián)網(wǎng)全棧架構(gòu)
        一、什么是注解
        注解是一種元數(shù)據(jù),可以應(yīng)用到代碼的多種元素上,比如類、字段、方法等,它提供了關(guān)于這些元素的額外信息,但不會影響程序的運(yùn)行邏輯。它主要有以下這些作用:
        為編譯器提供額外信息:編譯器可以用注解來檢測錯誤、抑制警告等。比如注解@Override,如果被修飾的方法沒有正確重寫父類的方法,那么編譯器就會報錯。又比如@Deprecated,它用來標(biāo)識一個方法已經(jīng)過時,建議不要繼續(xù)使用,編譯器也會給出相應(yīng)的警告提示。
        編譯時自動生成代碼:注解可以用于在編譯時自動生成代碼,從而減少開發(fā)人員的工作量以及一些不必要的錯誤,在一些框架中也經(jīng)??梢砸姷竭@種用法,比如Lombok。
        運(yùn)行時處理:在運(yùn)行時讀取并處理注解,從而改變程序的行為。這種情況在Spring框架中可以說是比比皆是了。

        生成文檔:另外,@Documented修飾的元素將會包含在生成的Java文檔中。

        二、內(nèi)置注解及元注解
        JDK本身自帶了一些常用的注解,主要有以下這些:

        而應(yīng)用于其他注解的注解,我們稱之為元注解,一共有五種元注解:

        三、自定義注解
        我們通過兩個簡單的案例來實(shí)際說明一下注解的用法。
         1. 通過反射讀取注解信息
        首先我們定義一個簡單的注解,它具有name和desc兩個屬性,然后在定義類的時候使用這個注解,并指定屬性的值,最后在測試類中獲取注解信息并打印:
        package com.sample.core.annotation;

        import java.lang.annotation.ElementType;
        import java.lang.annotation.Retention;
        import java.lang.annotation.RetentionPolicy;
        import java.lang.annotation.Target;

        // 自定義一個注解,有value有desc兩個屬性
        // 運(yùn)行時生效,可應(yīng)用于類、接口或者枚舉
        @Retention(RetentionPolicy.RUNTIME)
        @Target(ElementType.TYPE)
        public @interface MyAnnotation {
            String value();
            String desc();
        }
        package com.sample.core.annotation;

        @MyAnnotation(value = "full-stack", desc = "歡迎來到編程世界")
        public class MyClass {
        }
        package com.sample.core.annotation;

        // 通過反射獲取注解的信息
        public class AnnotationTest {
            public static void main(String[] args) {
                Class<MyClass> myClass = MyClass.class;
                MyAnnotation myAnnotation = myClass.getAnnotation(MyAnnotation.class);
                System.out.println(myAnnotation.value());
                System.out.println(myAnnotation.desc());
            }
        }
        2. Spring AOP自定義注解打印日志
        我們知道,Spring框架的兩大核心是IoC和AOP,而AOP表示面向切面編程,在無需修改代碼的前提下,對業(yè)務(wù)邏輯添加統(tǒng)一功能,比如事務(wù)、安全、日志等?,F(xiàn)在我們通過自定義注解的方式來實(shí)現(xiàn)日志打印功能,只要在方法上加上這個注解,就可以打印出日志,而無需在每個方法里面都加上日志打印的功能,大大提升了代碼的可維護(hù)性和簡潔性。
        這個例子基于Spring框架來完成,如果對于Spring Cloud Alibaba的項目搭建還不太熟練,請參考之前寫的一篇文章:手把手:Spring Cloud Alibaba項目搭建。
        先定義一個注解,它只包含level屬性,也就是日志級別的含義:
        package com.fullstack.commerce.user.util;

        import java.lang.annotation.ElementType;
        import java.lang.annotation.Retention;
        import java.lang.annotation.RetentionPolicy;
        import java.lang.annotation.Target;

        @Retention(RetentionPolicy.RUNTIME)
        @Target(ElementType.METHOD)
        public @interface MyLog {
            // 日志級別
            String level();
        }
        然后再定義一個注解處理器:
        package com.fullstack.commerce.user.util;

        import org.aspectj.lang.ProceedingJoinPoint;
        import org.aspectj.lang.annotation.*;
        import org.aspectj.lang.reflect.MethodSignature;
        import org.springframework.stereotype.Component;
        import java.lang.reflect.Method;

        // 這是一個切面類,同時交由Spring統(tǒng)一管理
        @Aspect
        @Component
        public class MyLogAspect {
            // 配置織入點(diǎn)
            @Pointcut("@annotation(MyLog)")
            private void logPointCut(){}

            // 環(huán)繞織入,在調(diào)用方法的前后執(zhí)行
            @Around("logPointCut()")
            public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {

                // 獲取方法名稱
                MethodSignature signature =(MethodSignature) joinPoint.getSignature();
                String methodName=signature.getName();

                // 獲取注解MyLog的參數(shù)值
                Method method = signature.getMethod();
                MyLog myLog=method.getAnnotation(MyLog.class);
                String level=myLog.level();

                // 打印日志
                System.out.println("方法名為:"+methodName+",日志級別為:"+level);
                long start = System.currentTimeMillis();
                // 注解方法繼續(xù)執(zhí)行
                Object result=joinPoint.proceed();
                System.out.println("方法的執(zhí)行時間為:" + (System.currentTimeMillis()-start)+"毫秒。");

                return result;
            }
        }

        這樣,統(tǒng)一打印日志的自定義注解就定義好了,接下來就是使用了。只需要在方法上加上@MyLog的注解,并指定它的level屬性值,方法在被調(diào)用時,就會自動打印日志,并在方法執(zhí)行完成后,打印出方法的執(zhí)行時間。我們在Controller的方法上加上這個注解,并且訪問這個方法,看看結(jié)果會是如何:
        package com.fullstack.commerce.user.controller;

        import com.fullstack.commerce.user.util.MyLog;
        import org.springframework.web.bind.annotation.GetMapping;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;

        @RestController
        @RequestMapping("hello")
        public class HelloController {

            @GetMapping("test")
            @MyLog(level = "info")
            public String test(){
                return "Hello World";
            }
        }

        在瀏覽器里面輸入:http://localhost:8080/hello/test,然后可以看到控制臺輸出如下:

        以上基于JDK8實(shí)現(xiàn)。另外,文章主要是講解自定義注解的使用,省去很多無關(guān)的細(xì)節(jié),在實(shí)際代碼編寫中,還需要根據(jù)業(yè)務(wù)場景的實(shí)際特點(diǎn)做相應(yīng)的豐富和改進(jìn)。

        都看到這里了,請幫忙一鍵三連啊,也就是點(diǎn)擊文末的在看、點(diǎn)贊、分享,這樣會讓我的文章讓更多人看到,也會大大地激勵我進(jìn)行更多的輸出,謝謝!

        鳴謝:

        https://docs.oracle.com/javase/tutorial/java/annotations/index.html


        推薦閱讀:

        “八面玲瓏”的ZooKeeper入門介紹

        一呼百應(yīng):監(jiān)聽變化的觀察者模式

        手把手:Spring Cloud Alibaba項目搭建

        春天的故事:Spring框架的入門級知識

        責(zé)無旁貸:超酷的責(zé)任鏈模式

        聚沙成塔:聊聊建造者模式

        公司裁員,碼農(nóng)竟然成了“幫兇”?(劇情杜撰)

        瀏覽 101
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            丝袜美腿一区二区三区 | 一级特黄6O分钟免费观看 | 尤物视频-ym193.cow | 日大逼黄片儿 | 爱福利视频一区二区 | 亚洲干逼| 中国精品少妇 | 国产精品国产三级国产普通话蜜臀 | 一级特黄高清免费播放直播 | 伊人成人日日夜夜 |