複習_自定義註解和動態代理

1.基本語法

1.1 註解的分類

按運行機制分

  • 源碼註解
    註解只存在於源碼中,編譯成.class文件就不存在了
  • 編譯時註解
    註解在源碼和.class文件中都存在
  • 運行時註解
    在運行階段還能起作用,甚至會影響運行邏輯的註解

按來源分

  • 來自JDK的註解
  • 來自第三方的註解
  • 我們自定義的註解

源註解
在這裏插入圖片描述
元註解類型 :
在這裏插入圖片描述
@Target 與 @Retention 取值類型 :
在這裏插入圖片描述

1.2 如何自定義註解

在這裏插入圖片描述
所有的Annotation自動實現java.lang.annotation.Annotation接口

註解支持類型:八種基本數據類型和String、Enum、Class、annotation以及以上類型的數組)

// 註解的作用域
@Target({ElementType.METHOD, ElementType.TYPE, ElementType.FIELD})
// 註解的生命週期
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Description {
    String desc();
    String author();
    int age() default 18;
}

public class Person {

    @Description(desc="帥哥", author = "wxf")
    public void introduce() {
        System.out.println("大家好, 我是王曉峯");
    }
}

1.3 解析

通過反射獲取類,方法,屬性上的註解
在這裏插入圖片描述

class Person {

    @Description(desc = "屬性上的註解", author = "wxf2")
    private String name;

    @Description(desc = "方法上的註解", author = "wxf3")
    public void introduce() {
        System.out.println("大家好, 我是王曉峯");
    }

    public static void main(String[] args) throws NoSuchMethodException {
        // 1.獲取Person類的Class對象
        Class<?> cls = Person.class;

        // 2.通過反射獲取到 introduce() 方法對象
        Method method = cls.getMethod("introduce", new Class[]{});

        // 3.判斷該方法上是否存在指定類型的註解
        if (method.isAnnotationPresent(Description.class)) {
            Description annotation = method.getAnnotation(Description.class);
            String desc = annotation.desc();
            String author = annotation.author();
            int age = annotation.age();
            System.out.println(desc + ", " + author + ", " + age);
        }
    }
}

聲明註解的屬性 :
如果註解中有一個名稱value的屬性,那麼使用註解時可以省略value=部分
特殊屬性value, String[] value;


2.動態代理

在這裏插入圖片描述

2.1 動態代理的代碼實現

// 接口
public interface ArithmeticInter {
    int sum(int num1, int num2);
    int minus(int num1, int num2);
    int multiply(int num1, int num2);
    int divide(int num1, int num2);
}

// 實現類
public class ArithmeticImpl1 implements ArithmeticInter {
    @Override
    public int sum(int num1, int num2) {
        int result = num1 + num2;
        return result;
    }

    @Override
    public int minus(int num1, int num2) {
        int result = num1 - num2;
        return result;
    }

    @Override
    public int multiply(int num1, int num2) {
        int result = num1 * num2;
        return result;
    }

    @Override
    public int divide(int num1, int num2) {
        int result = num1 / num2;
        return result;
    }
}

public static void main(String[] args) {
   // 1.創建一個實現類對象
   final ArithmeticInter arithmetic = new ArithmeticImpl1();

   // 2.使用動態代理實現方法的調用
   // 參數1: 類加載器
   ClassLoader loader = ArithmeticImpl1.class.getClassLoader();
   // 參數2: 被代理的類實現的所有接口
   Class<?>[] interfaces = ArithmeticImpl1.class.getInterfaces();
   // 參數3: InvocationHandler 接口, 動態代理具體處理的實現代碼, 一般都使用匿名內部類實現
   ArithmeticInter proxy = (ArithmeticInter) Proxy.newProxyInstance(loader, interfaces, new InvocationHandler() {
       @Override
       public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
           if (method.getName().endsWith("sum")) {
               System.out.println("相加開始");
               Object obj = method.invoke(arithmetic, objects);
               System.out.println("相加結束");
               return obj;
           }
           return method.invoke(arithmetic, objects);
       }
   });

   System.out.println(proxy.sum(10, 20));
   System.out.println(proxy.minus(20, 8));
   System.out.println(proxy.multiply(5, 5));
   System.out.println(proxy.divide(20, 5));
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章