<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 6226字,需瀏覽 13分鐘

           ·

          2023-10-17 06:42


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

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

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

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

          三、自定義注解
          我們通過兩個簡單的案例來實際說明一下注解的用法。
           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ī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ù)、安全、日志等。現(xiàn)在我們通過自定義注解的方式來實現(xiàn)日志打印功能,只要在方法上加上這個注解,就可以打印出日志,而無需在每個方法里面都加上日志打印的功能,大大提升了代碼的可維護性和簡潔性。
          這個例子基于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 {
              // 配置織入點
              @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實現(xiàn)。另外,文章主要是講解自定義注解的使用,省去很多無關(guān)的細節(jié),在實際代碼編寫中,還需要根據(jù)業(yè)務(wù)場景的實際特點做相應(yīng)的豐富和改進。

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

          鳴謝:

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


          推薦閱讀:

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

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

          手把手:Spring Cloud Alibaba項目搭建

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

          責無旁貸:超酷的責任鏈模式

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

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

          瀏覽 101
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天干天天色天天曹 | 亚洲中文成人娱乐网 | 午夜国产福利 | 影音先锋色噜噜av | 日本一级片免费看 |