Java注解开发

目录

1.Java注解的定义

2.Java注解的分类

    2.1.JDK基本注解

    2.2.JDK元注解

    2.3.JDK自定义注解

3.如何提取提取Annotation信息

4.注解处理器

    4.1为什么需要注解处理器

    4.2如何实现一个注解处理器


1.Java注解的定义

     Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到       说明、配置的功能

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

2.Java注解的分类

     三大注解:JDK基本注解、JDK元注解、JDK自定义注解

    2.1.JDK基本注解

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

    2.2.JDK元注解

        元注解用于修饰其他的注解(如纪委:管干部的干部),简单来说元注解就是管理注解的注解

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

       --2.2.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}),也就是此注解可以在方法和类上               面使用

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

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

        补充:根据Annotation是否包含成员变量,可以把Annotation分为两类:                                                ①标记Annotation: 
               没有成员变量的Annotation; 这种Annotation仅利用自身的存在与否来提供信息
            ②元数据Annotation: 
               包含成员变量的Annotation; 它们可以接受(和提供)更多的元数据
 

    2.3.JDK自定义注解

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

枚举(enum):使用枚举,就能把范围规定到“Read, Write, ReadWrite”当中,这样就可以避免范围外的数值

package com.zking.test.p1;

//枚举类
public enum TranscationModel {
    Read, Write, ReadWrite
}

MyAnnotation1.java:

​
package com.zking.test.p1;

import java.lang.annotation.*;


@Target({ElementType.TYPE, ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation1 {
    String name();
//    String value();

}

​

 MyAnnotation2.java:

package com.zking.test.p1;

import java.lang.annotation.*;


@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation2 {
    TranscationModel model() default TranscationModel.ReadWrite;
}

MyAnnotation3.java:

package com.zking.test.p1;

import java.lang.annotation.*;


@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
@Documented
public @interface MyAnnotation3 {
    TranscationModel[] models() default TranscationModel.ReadWrite;
}

Demo1:在该类中使用以上3个自定义注解来标识类和字段

package com.zking.test.p1;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

@MyAnnotation1(name = "abc")
public class Demo1 {

    @MyAnnotation1(name = "xyz")
    private Integer age;

    @MyAnnotation2(model = TranscationModel.Read)
    public void list() {
        System.out.println("list");
    }

    @MyAnnotation3(models = {TranscationModel.Read, TranscationModel.Write})
    @RequestMapping("/edit")
    @ResponseBody
    public void edit() {
        System.out.println("edit");
    }


}

3.如何提取Annotation信息

使用AnnotatedElement接口中的方法提取注解中的数据,像Class/Constructor/Field/Method/Package这些类都实现了AnnotatedElement接口。
注:只有当定义Annotation时使用了@Retention(RetentionPolicy.RUNTIME)修饰,JVM才会在装载class文件时提取保存在class文件中的Annotation,该Annotation才会在运行时可见,这样我们才能够解析

Demo1Test:通过以上的Demo1来提取Annotation信息

package com.zking.test;

import com.zking.test.p1.*;
import org.junit.Before;
import org.junit.Test;

import java.lang.reflect.Method;
import java.util.Arrays;

public class Demo1Test {
    @Before
    public void setUp() throws Exception {
    }

    @Test
    public void test1() throws Exception {
        MyAnnotation1 annotation = Demo1.class.getAnnotation(MyAnnotation1.class);
        System.out.println(annotation.name());

        //annotation = Demo1.class.getDeclaredField("age").getAnnotation(MyAnnotation1.class);
        //System.out.println(annotation.name());
    }

    @Test
    public void test2() throws Exception {
        Method method = Demo1.class.getMethod("list");
        System.out.println(method);
        MyAnnotation2 annotation2 = method.getAnnotation(MyAnnotation2.class);
        TranscationModel model = annotation2.model();
        System.out.println(model);
    }

    @Test
    public void test3() throws Exception {
        Method method = Demo1.class.getMethod("edit");
        System.out.println(method);
        MyAnnotation3 annotation3 = method.getAnnotation(MyAnnotation3.class);
        TranscationModel[] models = annotation3.models();
        System.out.println(Arrays.toString(models));
    }
}

test1():结果为abc

test2():先拿到 list 这个方法,再去提取该方法的Annotation信息,结果为Read

test3():先拿到 edit 这个方法,再去提取该方法的Annotation信息,你会发现以下类似的空指针问题的报错,是因为@Retention(RetentionPolicy.CLASS) 保留策略,注解会在class字节码文件中存在,但运行时无法获得

4.注解处理器

    4.1 为什么需要注解处理器

使用Annotation修饰了类/方法/成员变量等之后,这些Annotation不会自己生效,为了让程序中的这些注解起作用, 必须由这些注解的开发者为这些注解提供一个注解处理器(Annotation    Processor)。另外,在编译期间,JVM会自动运行注解处理器(当然,我们需要将其注册)

    4.2 如何实现一个注解处理器

        --4.2.1 定义注解

        --4.2.2 编写注解处理器

        --4.2.3 注册注解处理器 

        详细的实现过程可参考:https://blog.csdn.net/top_code/article/details/53968145

以上是我的学习记录,第一次写,略显生疏,若有错误,欢迎指正!

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值