SpringBoot之自定义注解详细介绍

SpringBoot之自定义注解详细介绍,第1张

SpringBoot之自定义注解详细介绍

目录

1.注解介绍

2.怎样自定义注解

2.1 注解基本语法

2.2 常用的元注解

2.2.1 @Target

2.2.2 @Retention

2.2.3 @documented

2.2.4 @Inherited

 3.自定义注解的使用

3.1定义注解

3.2 使用注解

3.3注解解析器 

 4.反射 *** 作获取注解 


1.注解介绍
    注解是一种元数据形式,即注解是属于java的一种数据类型,和类、接口、数组、枚举类似。注解用来修饰,类、方法、变量、参数、包。注解不会对所修饰的代码产生直接的影响。
2.怎样自定义注解

定义注解使用注解(将注解打在需要的代码上)解析注解(检测到标记并进行特殊 *** 作) 2.1 注解基本语法

注解类型声明

注解在Java中,与类、接口、枚举类似,因此其声明语法基本一致,只是所使用的关键字有所不同@interface在底层实现上,所有定义的注解都会自动继承java.lang.annotation.Annotation接口

public @interface MyLog {
  String value() default "";    
}

注解元素声明

访问修饰符必须为public,不写默认为public;该元素的类型只能是基本数据类型、String、Class、枚举类型;该元素的名称一般定义为名词,如果注解中只有一个元素,请把名字起为value(后面使用会带来便利 *** 作);()不是定义方法参数的地方,也不能在括号中定义任何参数,仅仅只是一个特殊的语法;default代表默认值,值必须和第2点定义的类型一致;如果没有默认值,代表后续使用注解时必须给该类型元素赋值。 2.2 常用的元注解

一个最基本的注解定义就只包括了上面的两部分内容:1、注解的名字;2、注解包含的类型元素。但是我们在使用注解的时候发现,有些注解只能写在方法上面;有些却可以写在类的上面 等等....那么这些是如何做的呢?

2.2.1 @Target

@Target注解,是专门用来限定某个自定义注解能够被应用在哪些Java元素上面的。

public enum ElementType {
    
    TYPE,

    
    FIELD,

    
    METHOD,

    
    PARAMETER,

    
    CONSTRUCTOR,

    
    LOCAL_VARIABLE,

    
    ANNOTATION_TYPE,

    
    PACKAGE
}
package com.wyy.Annotation;

import java.lang.annotation.*;

@Inherited
//当前注解只能放在方法以及类上
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@documented
public @interface MyLog {
    String value() default "";
}
2.2.2 @Retention

@Retention注解,定义注解的保留策略。

public enum RetentionPolicy {
    
    SOURCE,

    
    CLASS,

    
    RUNTIME
}

当注解被定义为RetentionPolicy.SOURCE,那么此注解只会出现Java源文件中,这个注解即不会参与编译也不会在运行时起任何作用。

当注解被定义为RetentionPolicy.CLASS,那么此注解将会被编译到class文件中,在运行期间同样不起任何作用。

当注解被定义为RetentionPolicy.RUNTIME,那么此注解可以在运行期间被加载到Class对象中。那么在程序运行阶段,我们可以通过反射得到这个注解及注解中的属性。

2.2.3 @documented

@documented注解,指定被修饰的该Annotation可以被javadoc工具提取成文档。

2.2.4 @Inherited

@Inherited注解,指定被修饰的Annotation将具有继承性 。

 3.自定义注解的使用 3.1定义注解
package com.wyy.Annotation;

import java.lang.annotation.*;

@Inherited
//当前注解只能放在方法以及类上
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@documented
public @interface MyLog {
    String value() default "";
}
3.2 使用注解
    @MyLog
    @RequestMapping("/hello")
    public String hello(){

        return "hello";
    }
3.3注解解析器 

这里以给方法添加日志为例

package com.wyy.Aspect;

import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Log4j2
public class MyLogAnnotation {

    
    @Pointcut("@annotation(com.wyy.Annotation.MyLog)")
    public void Mylog() {
    }

    
    @Around("Mylog()")
    public Object Mylogs(ProceedingJoinPoint proceedingJoinPoint) {
        //当前方法
        Signature methodName = proceedingJoinPoint.getSignature();
        //日志输出
        log.info(methodName + "方法开始执行");
        Object proceed = null;
        try {
            //执行方法
            proceed = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        //日志输出
        log.info(methodName + "方法执行结束");
        return proceed;

    }

}

当执行hello方法时 

 4.反射 *** 作获取注解 
public static void main(String[] args) {
        Annotation[] annotations = HelloController.class.getAnnotations();
        Arrays.asList(annotations).stream().forEach(System.out::println);

        try {
            Method hello = HelloController.class.getMethod("hello");
            if( hello.isAnnotationPresent(MyLog.class)){
                System.out.println("hello方法上配置MyLog注解");
                MyLog annotation = hello.getAnnotation(MyLog.class);
                String value = annotation.value();
                System.out.println("MyLog注解value参数的值:"+value);
            }else{
                System.out.println("hello方法上没有配置MyLog注解");
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

isAnnotationPresent(Class annotationClass)方法是专门判断该元素上是否配置有某个指定的注解。getAnnotation(Class annotationClass)方法是获取该元素上指定的注解。反射对象上还有一个方法getAnnotations(),该方法可以获得该对象身上配置的所有的注解。
 

运行结果:

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5707582.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存