• 自定义注解


    目录

    1. Java注解(Annotation) 

    2. Java注解分类

    3. JDK基本注解 

    4. JDK元注解 

     4.1 @Retention:定义注解的保留策略 

     4.2 @Target:指定被修饰的Annotation可以放置的位置(被修饰的目标) 

     4.3 @Inherited:指定被修饰的Annotation将具有继承性  

     4.4 @Documented:指定被修饰的该Annotation可以被javadoc工具提取成文档. 

    5. 注解分类 

    5.1 标记Annotation:  

    5.2 元数据Annotation: 

    6. 自定义注解开发 

    7. 提取Annotation信息 

     7.2 案例准备数据

     7.3 案例一:提供类的注解

     7.4 案例二:属性上的注解

     7.5 案例三:方法上的注解

    8. 动态注解处理器(spring aop方式)

     8.1  通过动态注解 spring aop方式 来做一个日志记录


     

    1. Java注解(Annotation) 

    Java注解是附加在代码中的一些元信息,用于一些工具在编译、


    运行时进行解析和使用,起到说明、配置的功能。

    注解相关类都包含在java.lang.annotation包中。

    2. Java注解分类

    2.1 JDK基本注解


    2.2 JDK元注解


    2.3 自定义注解 

    3. JDK基本注解 

    3.1 @Override
          重写
    3.2 @Deprecated
          已过时 
    3.3 @SuppressWarnings(value = "unchecked") 
          压制编辑器警告

    4. JDK元注解 

    元注解用于修饰其他的注解(纪委:管干部的干部) 

     4.1 @Retention:定义注解的保留策略 

    @Retention(RetentionPolicy.SOURCE)           //  注解仅存在于源码中,在class字节码文件中不包含
    @Retention(RetentionPolicy.CLASS)              //  默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
    @Retention(RetentionPolicy.RUNTIME)         //   注解会在class字节码文件中存在,在运行时可以通过反射获取到 

     4.2 @Target:指定被修饰的Annotation可以放置的位置(被修饰的目标) 

    @Target(ElementType.TYPE)                                // 接口、类
    @Target(ElementType.FIELD)                              //  属性
    @Target(ElementType.METHOD)                        //   方法
    @Target(ElementType.PARAMETER)                 //   方法参数
    @Target(ElementType.CONSTRUCTOR)            //   构造函数
    @Target(ElementType.LOCAL_VARIABLE)       //   局部变量
    @Target(ElementType.ANNOTATION_TYPE)     //   注解
    @Target(ElementType.PACKAGE)                      //   包 

    • 注:可以指定多个位置,例如: 

    @Target({ElementType.METHOD, ElementType.TYPE}),也就是此注解可以在方法和类上面使用

     4.3 @Inherited:指定被修饰的Annotation将具有继承性  

     4.4 @Documented:指定被修饰的该Annotation可以被javadoc工具提取成文档. 

     

    5. 注解分类 

    根据Annotation是否包含成员变量,可以把Annotation分为两类:  

     5.1 标记Annotation:  

    没有成员变量的Annotation; 这种Annotation仅利用自身的存在与否来提供信息 

    5.2 元数据Annotation: 

    包含成员变量的Annotation; 它们可以接受(和提供)更多的元数据; 

    6. 自定义注解开发 

    使用@interface关键字, 其定义过程与定义接口非常类似, 需要注意的是:   Annotation的成员变量在Annotation定义中是以无参的方法形式来声明的, 其方法名和返回值类型定义了该成员变量的名字和类型, 而且我们还可以使用default关键字为这个成员变量设定默认值

      例如: 

    1. @Inherited
    2. @Retention(RetentionPolicy.RUNTIME)
    3. @Target({ElementType.METHOD, ElementType.TYPE})
    4. public @interface Tag {
    5. String name() default "该叫啥才好呢?";
    6. String description() default "这家伙很懒, 啥也没留下...";
    7. }
    •  注1:只有名字为“value”属性,赋值时可以省略属性名

    7. 提取Annotation信息 

    使用AnnotatedElement接口中的方法提取注解中的数据,像Class/Constructor/Field/Method/Package这些类都实现了AnnotatedElement接口


       注:只有当定义Annotation时使用了@Retention(RetentionPolicy.RUNTIME)修饰,
           JVM才会在装载class文件时提取保存在class文件中的Annotation,该Annotation才会在运行时可见,这样我们才能够解析 

     7.2 案例准备数据

      Demo1

    1. package com.zking.ssm.annotation.p1;
    2. @MyAnnotation1(name = "abc")
    3. public class Demo1 {
    4. @MyAnnotation1(name = "xyz")
    5. private Integer age;
    6. @MyAnnotation2(model = TranscationModel.Read)
    7. public void list() {
    8. System.out.println("list");
    9. }
    10. @MyAnnotation3(models = {TranscationModel.Read, TranscationModel.Write})
    11. public void edit() {
    12. System.out.println("edit");
    13. }
    14. }

     MyAnnotation1

    1. package com.zking.ssm.annotation.p1;
    2. import java.lang.annotation.*;
    3. @Target({ElementType.TYPE, ElementType.FIELD,ElementType.METHOD})
    4. @Retention(RetentionPolicy.RUNTIME)
    5. @Documented
    6. public @interface MyAnnotation1 {
    7. String name();
    8. }

     MyAnnotation2

    1. package com.zking.ssm.annotation.p1;
    2. import java.lang.annotation.*;
    3. @Target(ElementType.METHOD)
    4. @Retention(RetentionPolicy.RUNTIME)
    5. @Documented
    6. public @interface MyAnnotation2 {
    7. TranscationModel model() default TranscationModel.ReadWrite;
    8. }

     MyAnnotation3

    1. package com.zking.ssm.annotation.p1;
    2. import java.lang.annotation.*;
    3. @Target(ElementType.METHOD)
    4. @Retention(RetentionPolicy.RUNTIME)
    5. @Documented
    6. public @interface MyAnnotation3 {
    7. TranscationModel[] models() default TranscationModel.ReadWrite;
    8. }

     TranscationModel

    1. package com.zking.ssm.annotation.p1;
    2. public enum TranscationModel {
    3. Read, Write, ReadWrite
    4. }

     

       7.3 案例一:提供类的注解

        创建一个类开始测试 

    1. package com.zking.ssm.annotation.p2;
    2. import com.zking.ssm.annotation.p1.*;
    3. import java.lang.reflect.Field;
    4. import java.lang.reflect.Method;
    5. import java.util.Arrays;
    6. public class Demo2 {
    7. public static void main(String[] args) throws Exception {
    8. //1.提供类上的注解
    9. //注意:元注解@Retention必须设置为RUNTIME
    10. MyAnnotation1 annotation = Demo1.class.getAnnotation(MyAnnotation1.class);
    11. System.out.println(annotation.name());
    12. }
    13. }

     7.4 案例二:属性上的注解

    1. package com.zking.ssm.annotation.p2;
    2. import com.zking.ssm.annotation.p1.*;
    3. import java.lang.reflect.Field;
    4. import java.lang.reflect.Method;
    5. import java.util.Arrays;
    6. public class Demo2 {
    7. public static void main(String[] args) throws Exception {
    8. //获取属性上的注解
    9. Field age = Demo1.class.getDeclaredField("age");
    10. age.setAccessible(true);//授权
    11. System.out.println(age);
    12. MyAnnotation1 annotation = age.getAnnotation(MyAnnotation1.class);
    13. String name = annotation.name();
    14. System.out.println(name);
    15. }
    16. }

     7.5 案例三:方法上的注解

    1. package com.zking.ssm.annotation.p2;
    2. import com.zking.ssm.annotation.p1.*;
    3. import java.lang.reflect.Field;
    4. import java.lang.reflect.Method;
    5. import java.util.Arrays;
    6. public class Demo2 {
    7. public static void main(String[] args) throws Exception {
    8. //获取方法上的注解
    9. Method method = Demo1.class.getMethod("list");
    10. System.out.println(method);
    11. MyAnnotation2 annotation2 = method.getAnnotation(MyAnnotation2.class);
    12. TranscationModel model = annotation2.model();
    13. System.out.println(model);
    14. //获取方法上的注解,数组
    15. Method method = Demo1.class.getMethod("edit");
    16. System.out.println(method);
    17. MyAnnotation3 annotation3 = method.getAnnotation(MyAnnotation3.class);
    18. TranscationModel[] models = annotation3.models();
    19. System.out.println(Arrays.toString(models));
    20. }
    21. }

     

    8. 动态注解处理器(spring aop方式)

         提问spring aop是什么?  

    答:

    1)连接点(JoinPoint):在程序执行过程中明确的点,列如:方法的调用,异常的抛出

    2)目标:被代理(被通知)的对象,执行具体核心业务逻辑

    3)通知:在某种特定的连接点上所执行的动作

    4)代理:将通知应用到目标后所得到的对象叫做代理对象,只有完整的代理对象才具有AOP特性 适配器+切入点

     8.1  通过动态注解 spring aop方式 来做一个日志记录

     Demo3

    1. package com.zking.ssm.annotation.p3;
    2. import org.springframework.stereotype.Component;
    3. @Component
    4. public class Demo3 {
    5. private Integer age;
    6. @MyLog(desc = "测试测试!!!")
    7. public void hello(String name) {
    8. System.out.println("hello:" + name);
    9. }
    10. //测试类调用这个方法不会出现日志
    11. public void add(int a,int b){
    12. System.out.println("add" + a + b);
    13. }
    14. }

     MyLog 

    1. package com.zking.ssm.annotation.p3;
    2. import java.lang.annotation.ElementType;
    3. import java.lang.annotation.Retention;
    4. import java.lang.annotation.RetentionPolicy;
    5. import java.lang.annotation.Target;
    6. @Target(ElementType.METHOD)
    7. @Retention(RetentionPolicy.RUNTIME)
    8. public @interface MyLog {
    9. String desc();
    10. }

     MyLogAspect(核心切面类

    1. package com.zking.ssm.annotation.p3;
    2. import org.aspectj.lang.JoinPoint;
    3. import org.aspectj.lang.Signature;
    4. import org.aspectj.lang.annotation.Aspect;
    5. import org.aspectj.lang.annotation.Before;
    6. import org.aspectj.lang.annotation.Pointcut;
    7. import org.aspectj.lang.reflect.MethodSignature;
    8. import org.slf4j.Logger;
    9. import org.slf4j.LoggerFactory;
    10. import org.springframework.stereotype.Component;
    11. import java.lang.reflect.Method;
    12. @Component
    13. @Aspect
    14. public class MyLogAspect {
    15. private static final Logger log = LoggerFactory.getLogger(MyLogAspect.class);
    16. @Pointcut("@annotation(com.zking.ssm.annotation.p3.MyLog)")
    17. private void MyValid() {
    18. }
    19. @Before("MyValid()")
    20. public void before(JoinPoint joinPoint) {
    21. Signature signature = joinPoint.getSignature();
    22. MethodSignature methodSignature = (MethodSignature) signature;
    23. Method method = methodSignature.getMethod();
    24. MyLog annotation= method.getAnnotation(MyLog.class);
    25. log.debug(annotation.desc());
    26. log.debug("[" + joinPoint.getSignature().getName() + " : start.....]");
    27. }
    28. }

     创建测试类 开始测试

    1. package com.zking.ssm.service.impl;
    2. import com.zking.ssm.annotation.p3.Demo3;
    3. import org.junit.Test;
    4. import javax.annotation.Resource;
    5. /**
    6. * @author 蒋明辉
    7. * @data 2022/9/25 22:33
    8. */
    9. public class Demo3Test extends BaseTest{
    10. //注入
    11. @Resource
    12. private Demo3 demo3;
    13. @Test
    14. public void Demo01(){
    15. demo3.hello("蒋明辉每天都很可爱");
    16. }
    17. }
    •  控制台查看日志 

  • 相关阅读:
    vs2019 libtiff安装及应用
    KDD2022 Learning Backward Compatible Embeddings【个人笔记】
    474. 一和零
    centos7.9安装nacos
    项目笔记-瑞吉外卖(全)
    【pip】查找某个版本的安装包
    Nacos注册中心
    【论文阅读】基于隐蔽带宽的汽车控制网络鲁棒认证(二)
    京东小程序数据中心架构设计与最佳实践
    国际腾讯云:云服务器疑似被病毒入侵问题解决方案!!!
  • 原文地址:https://blog.csdn.net/m0_63300795/article/details/127044714