Annotation实战【自定义AbstractProcessor】
前言
在使用Java的过程中,每个开发人员都接触过@Override, @Deprecated等等各式各样的注解,这些东西是java最基础的一些原生定义好的annotation。本文通过一个实例演示如果自定义自己的annotation,使得在编译源码代码阶段进行额外操作。案例源码
预热
简单说一下annotation的基本知识,从java的官方技术文档可以直接找到annotation的技术点。
Annotations, a form of metadata, provide data about a program that is not part of the program itself. Annotations have no direct effect on the operation of the code they annotate.
Annotations是一种元数据,其作用在于提供程序本身以外的一些数据信息,也就是说Annotation他不会属于程序代码本身,不参与逻辑运算,故而不会对原程序代码的操作产生直接的影响。
一般来说Annotation有如下三种使用情形:
- Information for the compiler — Annotations can be used by the compiler to detect errors or suppress * warnings.
- Compile-time and deployment-time processing — Software tools can process annotation information to generate code, XML files, and so forth.
- Runtime processing — Some annotations are available to be examined at runtime.
- 为编译器提供辅助信息 — Annotations可以为编译器提供而外信息,以便于检测错误,抑制警告等.
- 编译源代码时进行而外操作 — 软件工具可以通过处理Annotation信息来生成原代码,xml文件等等.
- 运行时处理 — 有一些annotation甚至可以在程序运行时被检测,使用.
具体annotation的详细知识点可以参考技术文档,本文案例针对的是编译源代码时进行而外操作。
目标
用过顶顶大名的Dagger,Butterknife等依赖注入的童鞋可能知道,他们就通过运行时annotation预处理技术实现动态的生成代码。现在我们先做一个简单的案例:
通过定义一个annotation,在编译代码的时候,凡是用该annotation声明过的类,方法,我们都要在控制台输出他们的信息
下文涉及的编码等工作是基于IntelliJ Idea和Android Studio,读者也可以根据自己的实际情况选用其他诸如Eclipse的工具。
开工
首先用IntelliJ新建一个java标准工程,同时勾选maven支持,我们需要新建一个自己的AbstractProcessor类, 其中process为主要方法,在里面处理接收到的所有被PrintMe修饰过的元素,这里是直接输出器信息。
@SupportedAnnotationTypes({"com.avenwu.annotation.PrintMe"})
public class MyProcessor extends AbstractProcessor {public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {Messager messager = processingEnv.getMessager();for (TypeElement te : annotations) {for (Element e : env.getElementsAnnotatedWith(te)) {messager.printMessage(Diagnostic.Kind.NOTE, "Printing: " + e.toString());}}return true;}@Overridepublic SourceVersion getSupportedSourceVersion() {return SourceVersion.latestSupported();}
}
现在新建PrintMe,简单起见现在可以什么不写,仅需标注其使用策略为RetentionPolicy.SOURCE
@Retention(RetentionPolicy.SOURCE)
public @interface PrintMe {
}
现在我们需要生成jar文件,修改pom.xml,默认生成的pom.xml需要再添加jar,和maven-compiler-plugin,修改完毕后应该如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>groupId</groupId><artifactId>AnnotationProcessorTest</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><build><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><version>2.3.2</version><configuration><source>1.6</source><target>1.6</target><!-- Disable annotation processing for ourselves. --><compilerArgument>-proc:none</compilerArgument></configuration></plugin></plugins></build>
</project>
为了我们的AbstractProcessor内被使用,需要在META-INF中显示标识,在resources资源文件夹下新建META-INF/services/javax.annotation.processing.Processor
com.avenwu.annotation.MyProcessor
至此可以build生成jar了。
同时我们可以看一下生成的jar里面都有什么东西:
测试
现在我们需要测试一下生成的jar包是不是如预期能输出信息。将AnnotationProcessorTest.jar拷贝置一个测试项目的libs,然后在任意选择几个位置用PrintMe修饰:
现在编译测试项目,在输出console了面观察日志
参考
- http://en.wikipedia.org/wiki/Java_annotation
- http://docs.oracle.com/javase/tutorial/java/annotations/
- http://programmaticallyspeaking.com/playing-with-java-annotation-processing.html
- https://github.com/provegard/aptdemo
Annotation实战【自定义AbstractProcessor】相关推荐
- 深入理解Java注解Annotation及自定义注解
要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法. 元注解: 元注解的作用就是负责注解其他注解.Java5. ...
- 深入理解Java:注解(Annotation)自定义注解入门
要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法. 元注解: 元注解的作用就是负责注解其他注解.Java5. ...
- Android项目开发实战—自定义左右菜单
Android实现自定义左右菜单 功能描述: 在左中右三个区域分别承载三个不同的view,把它全部添加进来,而我们实现左右菜单,就是来控制当前显示的是哪一部分:如果显示中间菜单,就把中间菜单呈现在用户 ...
- java注释和注解_深入理解JAVA注解(Annotation)以及自定义注解
Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制.Java 语言中的类.方法.变量.参数和包等都可以被标注.注解可以看作是一种特殊的标记,在程序在编译或 ...
- spring aop 中@annotation()和自定义注解的使用
在自定义个注解之后,通过这个注解,标注需要切入的方法,同时把需要的参数传到切面去.那么我们怎么在切面使用这个注解. 我们使用这个自定义注解一方面是为了传一些参数,另一方面也是为了省事. 具体怎么省事, ...
- JavaWeb框架(一):Web入门,Http的请求和响应,https介绍,Web实战自定义服务器
Servlet入门 MVC实战项目 仓储管理系统 JavaWeb入门介绍 Http协议 Http请求数据格式 Http响应数据格式 Web实战Demo:自定义服务器 对比Https协议 总结 Redi ...
- vue3 | HighCharts实战自定义封装之径向条形图
1.前言 目前正在做vue3的数据可视化项目,vue3的组合式api写法十分方便,可以有各种玩法,有兴趣的同学可以看我个人主页的其他文章.难点是在网上找了一圈的有关径向条形图的示例都没有好的解决方案, ...
- Flutter实战-自定义键盘(二)
用了两年的flutter,有了一些心得,从今天开始陆续更新一些案例,不虚头巴脑,只求实战有用,以供学习或使用flutter的小伙伴参考,学习尚浅,如有不正确的地方还望各路大神指正,以免误人子弟,在此拜 ...
- Flutter实战-自定义键盘(一)
用了两年的flutter,有了一些心得,从今天开始陆续更新一些案例,不虚头巴脑,只求实战有用,以供学习或使用flutter的小伙伴参考,学习尚浅,如有不正确的地方还望各路大神指正,以免误人子弟,在此拜 ...
最新文章
- zabbix_agentd.conf配置文件详解
- https ssl 非对称加密
- ToDesk远程控制软件
- linux中运行.pro文件,Linux下pro*c运行配置
- 数据库降级_阿里 双11 同款流控降级组件 Sentinel Go 正式GA,云原生服务稳稳稳...
- Nginx静态资源盗链的效果展示
- 用区块链打击假新闻 这可能是最2017年的一件事
- php ajax 表格编辑,php ajax表格实时编辑 PHP Ajax实现表格实时编辑
- 对页面文章过长的处理方法
- 利用numpy删除DataFrame某一行/列、多行内容
- jframe运行和预览大小不一样_在泉州楼市中12个热门置业板块中,购房竞争压力大小各不一样...
- 软件架构(10)---java资深架构师分布式技术分享
- shell基础07 函数
- 《Unix环境高级编程》读书笔记 第5章-标准I/O流
- consul命令行查看服务_Go语言微服务架构实战:第十三节 微服务管理--Docker安装及运行consul节点...
- WPF自适应可关闭的TabControl 类似浏览器的标签页
- Visual C++ 6.0 Processor Pack 编译xvidcore1.1.0
- 千方百剂2008升级到千方百计II 脚本执行错误 请检查第69行
- excel取消隐藏_Excel教程:一键取消隐藏工作表
- 鸿蒙支持ps4手柄吗,完美兼容PS4手柄!iPhone也能畅玩PS4,教程在此
热门文章
- android 输入金额,EditText输入金额保留两位小数点
- ibatis mysql_mysql +ibatis
- axios安装_一起学Vue:访问API(axios)
- android电视怎么升级失败,智能电视升级失败,原因都在这里!
- IntelliJ IDEA 14.0 添加及显示 JDK DOC
- 安卓学习笔记18:常用控件 - 按钮、图像视图和图像按钮
- 爬虫练习:爬豆瓣读书的短评
- 5.过滤器作为模板——寻找沃尔多、不相同的模板匹配_3
- Be动词的缩写形式_3
- java 数组合并_数组与链表