Java自定义注解
本篇文章的主要内容关于Java自定义注解。
什么是注解
Annotation(注解)就是Java提供了一种元程序中的元素关联任何信息和着任何元数据(metadata)的途径和方法。
Annotion(注解)是一个接口,程序可以通过反射来获取指定程序元素的 Annotion对象,然后通过 Annotion对象来获取注解里面的元数据。
元注解
Java元注解是用于定义和处理其他注解的特殊注解。元注解本身并不直接应用于代码的元素(类、方法、字段等),而是用于修改或解释其他注解。Java中有四个标准的元注解,它们可以用于自定义注解,并对注解的行为进行控制:
@Retention
: 用于指定注解的保留策略,即注解在何时可见。它有以下三个策略:RetentionPolicy.SOURCE
: 注解仅保留在源代码中,编译后不会包含在class文件中。RetentionPolicy.CLASS
: 注解保留在class文件中,但在运行时不可访问。RetentionPolicy.RUNTIME
: 注解保留在class文件中,并在运行时可通过反射访问。
@Target
: 用于指定注解可以应用的目标元素类型。它有以下常用选项:ElementType.TYPE
: 可以应用于类、接口或枚举。ElementType.METHOD
: 可以应用于方法。ElementType.FIELD
: 可以应用于字段或属性。ElementType.PARAMETER
: 可以应用于方法参数。ElementType.CONSTRUCTOR
: 可以应用于构造函数。ElementType.LOCAL_VARIABLE
: 可以应用于局部变量。ElementType.ANNOTATION_TYPE
: 可以应用于其他注解。ElementType.PACKAGE
: 可以应用于包声明。
@Documented
: 用于指定注解是否包含在Java文档中。如果一个注解被@Documented
标记,它将包含在生成的Java文档中,否则不会出现在文档中。@Inherited
: 用于指定注解是否可以被继承。如果一个注解被@Inherited
标记,且应用于一个类,那么这个类的子类将自动继承该注解。但要注意,只有在类级别上使用的注解才会被继承,对方法或字段的注解不会被继承。
自定义注解
创建
1 | package annotation; |
解析
以下是注解的功能:
主要步骤就是
- 通过反射获取类型 :
Class<?> clazz = obj.getClass();
- 通过
clazz.isAnnotationPresent(MyCustomAnnotation.class)
来检查是否有指定注解, - 获取注解实例:
MyCustomAnnotation classAnnotation = clazz.getAnnotation(MyCustomAnnotation.class);
- do something …
1 | package annotation; |
测试类:
1 | package annotation; |
输出:
1 | Class Annotation: MyClass annotation |
注解自动扫描
现在这个注解的使用,是在AnnotationProcessor中通过创建一个示例类obj ,再获取这个obj 的Class对象进行解析。那么如何实现自动的扫描和解析呢?
实现自动的扫描和解析注解通常涉及两个主要步骤:类路径扫描和注解解析。
类路径扫描是为了找到所有包含自定义注解的类,而注解解析则是在找到这些类后,对它们进行具体的注解处理。
我们可以通过反射和类路径扫描技术来实现自动的注解扫描和解析。
以下是一个类路径扫描技术实现思路:
- 获取当前线程的类加载器:首先,我们通过
Thread.currentThread().getContextClassLoader()
方法获取当前线程的类加载器。类加载器用于从类路径中加载类和资源文件。 - 将包名转换为资源路径:将包名中的点号
.
替换为斜杠/
,形成资源文件的路径形式。例如,将包名com.example.myapp
转换为com/example/myapp
。 - 在类路径下搜索资源文件:使用类加载器的
getResources()
方法,在类路径下搜索包含指定包名的所有资源文件。这些资源文件可能是目录,也可能是Jar文件。 - 遍历资源文件:遍历找到的资源文件,对于每个资源文件,进行如下处理:
- 如果资源文件是目录,则递归处理该目录,继续寻找其他资源文件。
- 如果资源文件是Jar文件,则读取该Jar文件,遍历其中的所有类,并将包含指定包名的类进行处理。
- 加载并处理类:对于找到的每个类,使用
Class.forName()
方法加载类,然后进行注解解析或其他处理逻辑。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 罗辑往事!