目录
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.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 extends Annotation> annotationClass)方法是专门判断该元素上是否配置有某个指定的注解。getAnnotation(Class annotationClass)方法是获取该元素上指定的注解。反射对象上还有一个方法getAnnotations(),该方法可以获得该对象身上配置的所有的注解。
运行结果:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)