Java注解学习总结

一:注解基础学习

注解从含义上讲是一种元数据,本质上只是对代码的一种注释说明,因为有了注解的解析才有了相应的功能。如果没有注解解析产生功能,它还不如注释清晰。从结构上看,注解编译后就是一个接口

元注解

元注解:元注解是一种基本注解,在定义注解时使用,主要定义注解的作用域,生命周期等等

  1. @Retention:定义注解的生命周期
    • RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
    • RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
    • RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们
  2. @Documented
    将注解中的元素包含到 Javadoc 中去。
  3. @Target
    限定了运用的场景。方法,字段,类。ElementType列举了枚举值表示作用域
  4. @Inherited
    如果一个注解使用@Inherited标记,那么使用当前注解的类的子类自动添加当前注解(子类没有显式使用注解)
  5. @Repeatable
    java8开始引入,定义的注解可以在同一个地方重复使用

注解的定义和属性

注解定义关键字是@interface,注解只有成员变量,没有方法。方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型
在这里插入图片描述
定义了 TestAnnotation 这个注解中拥有 id 和 msg 两个属性。在使用的时候,我们应该给它们进行赋值。赋值的方式是在注解的括号内以 value=”” 形式,多个属性之前用 ,隔开。
在这里插入图片描述
注意点:

  1. 定义属性时它的类型必须是 8 种基本数据类型外加 类、接口、注解及它们的数组
  2. 可以给属性设置默认值
public int id() default -1;
  1. 一个注解内仅仅只有一个名字为 value 的属性时,应用这个注解时可以直接接属性值填写到括号内。如果有多个属性,使用时省略属性名默认指的就是value属性

二:编译时解析注解

在使用javac编译java代码时,通过APT(注解处理器)技术获取.java文件中的注解信息,生成新的java代码(可以使用javapoet生成代码),可以实现一些功能。例如:lombok工具包

使用APT;
步骤1:继承AbstractProcessor,重写process方法
使用@AutoService生成META-INF\services\javax.annotation.processing.Processor

@AutoService的pom

<dependency>
	<groupId>com.google.auto.service</groupId>
	<artifactId>auto-service</artifactId>
	<version>1.0-rc6</version>
</dependency>

使用:
在这里插入图片描述
process生成helloworld

public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
		 System.out.println("------ process -----");
	        //MethodSpec这个类是要引入'com.squareup:javapoet:1.8.0'包,方便通过代码创建java文件
	        MethodSpec main = MethodSpec.methodBuilder("main")
	                //.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
	                .returns(void.class)
	                .addParameter(String[].class, "args")
	                .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")
	                .build();
	        TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
	                //netstat -an | grep .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
	                .addMethod(main)
	                .build();

	        JavaFile javaFile = JavaFile.builder("com.txd.annotaionlearn", helloWorld)
	                .build();
	        try {
	            //这里的输出要在Gradle Console中看
	            javaFile.writeTo(System.out);
                javaFile.writeTo(new File("E:\\10.workspace\\2.ST(4.0)\\test\\src\\main\\java\\com\\txd\\annotaionlearn\\model"));
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	        return false;
	}

编译,安装到本地仓库,clean install

步骤2:在maven工程中使用以上的自定义注解处理器,涉及2个插件
maven-processor-plugin和maven-compiler-plugin
此处我通过maven-compiler-plugin来使用自定义annotationprocessor
在这里插入图片描述
然后,mvn clean compile
会发现在控制台上:
在这里插入图片描述
本地生成helloworld文件
在这里插入图片描述

此次生成代码用到了java类库javapoet

三:运行时解析注解

注解类型必须是:@Retention(RetentionPolicy.RUNTIME)
运用反射技术提取注解:使用Class 对象的几个方法

public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass){} ;
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {};
public Annotation[] getAnnotations() {};

然后就可以获取注解上的参数,做逻辑处理

四:spi使用@AutoService

spi在很多地方已经有使用:jdbc4.0以后,dubbo

五:常见的操作源代码字节码的库

字节码:javasist,cglib,ASM
源码:Javapoet

五:参考博客

  1. https://www.cnblogs.com/guyuehuanhuan/p/9185899.html
  2. https://juejin.im/entry/585617d6128fe1006994f992
  3. https://www.jianshu.com/p/c04619b37440
  4. https://blog.csdn.net/jjxojm/article/details/90349756
  5. https://www.jianshu.com/p/086fe09188ea
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章