java注解使用以及如何实现一个自定义注解

注解知识点

一、注解的概念及作用

1.什么是注解

源代码中元数据的一种标记,注解本质上是一个继承自Annotation的类(一般通过反射的方式实现具体的功能)

2.注解的作用
  • 生成文档,根据文档注解,可以生成java文档
  • 追踪代码依赖性,实现替代配置文件功能(最主要的功能)
  • 在编译时进行格式检查,告知编译器哪些代码需要检查

二、注解的分类

1.按来源分
(1)JDK注解

第一种:元注解

元注解就是用来定义注解的注解

  • @Target : 是注解的作用域,表示该注解可以用于一个类中的那些属性及方法上,如果作用域类型有多个用英文逗号分隔(空间上的有效范围)

Target的可选值

注:上面的这些常量需要通过枚举类ElementType来引用,如ElementType.METHOD

  • @Retention : 注解的生命周期,表明该注解在什么时候起作用,什么时候失效(时间上的有效范围)

Retention的可选值

注:上面的这些常量需要通过枚举类RetentionPolicy来引用,如RetentionPolicy.RUNTIME

  • @Inherited:此注解是标识性的元注解,表示当前注解可以由子注解来继承
  • @Documented:表示生成javadoc的时候会包含注解

第二种:普通注解

(2)第三方类库或框架注解

由第三方类库或框架定义的注解,比如Spring中的注解@Controller

(3)自定义注解

自身项目根据项目需要实现的针对项目的自定义注解

2.按作用的生命周期分
  • 源码注解:在源码时起作用,在编译时失效
  • 编译时注解:在编译时起作用,在运行时失效
  • 运行时注解:只在运行时起作用

三、注解的使用

1.使用jdk注解和第三方注解

在使用jdk注解或第三方注解,只需要在使用的地方直接标注注解即可

(1)使用jdk的注解

  1. @Documented
  2. public User {
  3. }

(2)使用Spring的注解

  1. @Controller
  2. public class HelloController {
  3. }
2.使用自定义注解

注:注解只是一种标记,如果不解析,它是不会实现任何功能的

(1)定义注解:定义标记

定义标记需要使用元注解

  • 使用元注解@Target来标记该注解的作用范围(空间范围,在哪些地方可以使用)
  • 使用元注解@Retention来标记该注解的作用时间范围(时间范围,在什么时候起作用)
  • 使用元注解@Inherited来标记该注解是否可以由子注解来继承
  • 使用元注解@Documented来标记该注解是否需要自动生成文档
  • 使用@interface关键词来定义注解
  • 在注解内部定义一些相关的属性,一般是方法的形式来定义属性
  1. package main.java.com.shixinke.java.demo.annotation;
  2. import java.lang.annotation.*;
  3. @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
  4. @Retention(RetentionPolicy.RUNTIME)
  5. @Inherited
  6. @Documented
  7. public @interface Check {
  8. boolean value() default false;
  9. }

注:自定义注解本质上是继承自Annotation的类

(2)标记注解:打标,表明此处要使用此标记

定义一个User类,标记为@Check

  1. package main.java.com.shixinke.java.demo.annotation;
  2. @Check(true)
  3. public class User {
  4. }

定义一个Person类,不标记

  1. package main.java.com.shixinke.java.demo.annotation;
  2. public class Person {
  3. }
(3)解析注解:扫描标记,实现功能

一般通过反射来实现扫描注解,并在解析器中实现功能:

  • 注解解析器来解析注解并实现功能
  1. package main.java.com.shixinke.java.demo.annotation;
  2. import java.lang.annotation.Annotation;
  3. public class CheckParser {
  4. public void parse(Class cls) {
  5. /**
  6. * 获取Check的注解对象
  7. */
  8. Annotation annotation = cls.getAnnotation(Check.class);
  9. Check check = (Check) annotation;
  10. /**
  11. * 检查是否有Check注解,并且注解的value属性为true
  12. */
  13. if (check != null && check.value()) {
  14. System.out.println(cls.getName()+"在检查中........");
  15. }
  16. }
  17. }
  • 调用注解解析器
  1. package main.java.com.shixinke.java.demo.annotation;
  2. public class AnnotationDemo {
  3. public static void main(String[] args) {
  4. User user = new User();
  5. Person person = new Person();
  6. CheckParser parser = new CheckParser();
  7. parser.parse(user.getClass()); //main.java.com.shixinke.java.demo.annotation.User在检查中........
  8. parser.parse(person.getClass());
  9. }
  10. }