博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
记一次注解处理器的开发过程
阅读量:5036 次
发布时间:2019-06-12

本文共 2674 字,大约阅读时间需要 8 分钟。

目录

需求描述

开发一个扫描所有注解信息的脚本程序,希望在编译期对代码进行扫描,如果注解书写不规范则使编译失败。

本次的需求刚好用AbstractProcessor可以满足,在这次需求中我学习到了注解处理器的开发,并且踩了一些坑,在这里记录下来,希望能够帮助其他人在开发的时候避免。

AbstractProcessor

简介

我们在网上搜索到的AbstractProcessor,大多用于Android开发时用到,但实际上注解处理器在我们的工作中仍然也能起到很大的作用。

注解的处理除了可以在运行时通过反射机制处理外,还可以在编译期进行处理。在编译期处理注解时,会处理到不再产生新的源文件为止,之后再对所有源文件进行编译。

Java5中提供了apt工具来进行编译期的注解处理。apt是命令行工具,与之配套的是一套描述“程序在编译时刻的静态结构”的API:Mirror API(com.sun.mirror.*)。通过Mirror API可以获取到被注解的Java类型元素的信息,从而提供自定义的处理逻辑。具体的处理工具交给apt来处理。编写注解处理器的核心是两个类:注解处理器(com.sun.mirror.apt.AnnotationProcessor)、注解处理器工厂(com.sun.mirror.apt.AnnotationProcessorFactory)。apt工具在完成注解处理后,会自动调用javac来编译处理完成后的源代码。然而,apt工具是oracle提供的私有实现(在JDK开发包的类库中是不存在的)。在 Java8中,已经移除了 APT 工具;在JDK6中,将注解处理器这一功能进行了规范化,形成了java.annotation.processing的API包,Mirror API则进行封装,形成javax.lang.model包。注解处理器的开发进行了简化,不再单独使用apt工具,而将此功能集成到了javac命令中。(当前开发使用的JDK版本一般都在6以上,故对apt工具不做研究)。

简单来讲,就是 我们可以通过使用 AbstractProcessor 可以在编译期处理所有指定的注解。

AbstractProcessor,是一个抽象类,该类实现了接口Processor。处理接口提供了一个核心处理方法process(),用于开发者实现自己的处理逻辑(用于处理先前round中产生的注解)。

boolean process(Set
annotations, RoundEnvironment roundEnv);

process()方法有一个boolean类型的返回值,若返回false,表示本轮注解未声明并且可能要求后续其它的Processor处理它们;若返回true,则代表这些注解已经声明并且不要求后续Processor来处理它们。

开发

我们暂时不需要考虑其他方法的实现,这些操作我们也不需要,我们只需要指定需要处理的注解,指定编译的Java版本,并且实现核心逻辑process()方法就可以了。

@SupportedAnnotationTypes({"XXX"})//指定注解的类型@SupportedSourceVersion(SourceVersion.RELEASE_8)//指定支持的Java版本,这里是Java8public class VUAnnotationProcessor extends AbstractProcessor {      // annotations为要求处理的注解类型    // roundEnv 中包含了当前和上一轮的环境信息,从中我们可以获取扫描出来的注解实例    @Override    public boolean process(Set
annotations, RoundEnvironment roundEnv) { //在这里书写处理逻辑 return true; }}

声明

这些开发完了之后,我们需要在resources目录下创建META-INF/services目录,在其下创建javax.annotation.processing.Processor文件,并在其中填写我们自定义的注解处理器的全类名。

坑:服务配置文件不正确

我们在开发完进行编译,很快会在控制台发现这行错误

错误: 服务配置文件不正确, 或构造处理程序对象javax.annotation.processing.Processor: XXX could not be instantiated: java.lang.NoClassDefFoundError: XXX 时抛出异常错误

为什么呢?因为注解处理器在启动的时候,注解处理器本身还没有编译,所以找不到。WTF。

那么,同学们,怎么才能解决这个“鸡生蛋,蛋生鸡”的问题呢?

第一,把这个类拆到单独的Jar包里面,不要让它干扰到需要扫描的项目里。

第二,在这个单独的项目里,引入声明,表示,这个项目不要用注解处理器扫描。

org.apache.maven.plugins
maven-compiler-plugin
2.0.2
default-compile
-proc:none
1.8
1.8

这样才能让这个类编译成功,并且让它在其他项目编译的时候生效。

参考

https://blog.zenfery.cc/archives/78.html

转载于:https://www.cnblogs.com/coder-chi/p/11316136.html

你可能感兴趣的文章
目前国内几大著名报表软件(2014更新)
查看>>
我想要得那块牌—记烟台大学第一届"ACM讲堂"
查看>>
【LaTeX排版】LaTeX论文模版
查看>>
事务管理
查看>>
Http协议中Cookie详细介绍
查看>>
15Spring泛型依赖注入
查看>>
[k8s]k8s api-server启动systemd参数分析
查看>>
Visio 入门教程
查看>>
VxLAN
查看>>
mysql-5.7.17的最新安装教程
查看>>
mysql 如何实现跨裤查询
查看>>
深度工作:充分使用每一份脑力
查看>>
redis的string类型操作命令
查看>>
一步一步学Linq to sql(一):预备知识
查看>>
全排列(传统&&黑科技)
查看>>
plist文件
查看>>
SSM Maven MallDemo项目为例
查看>>
NopCommerce 1.9 2.0 2.1 设置连接字符串
查看>>
当form表单中只有一个input时按回车键将会自动将表单提交
查看>>
题目:返回一个整数数组中最大子数组的和。
查看>>