前言

在使用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;
} @Override
public 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了面观察日志

参考

  1. http://en.wikipedia.org/wiki/Java_annotation
  2. http://docs.oracle.com/javase/tutorial/java/annotations/
  3. http://programmaticallyspeaking.com/playing-with-java-annotation-processing.html
  4. https://github.com/provegard/aptdemo

Annotation实战【自定义AbstractProcessor】的更多相关文章

  1. [2]注解(Annotation)-- 深入理解Java:注解(Annotation)自定义注解入门

    转载 http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 深入理解Java:注解(Annotation)自定义注解入门 要深入学习 ...

  2. Java注解Annotation与自定义注解详解

    Java注解简介 开发中经常使用到注解,在项目中也偶尔会见到过自定义注解,今天就来探讨一下这个注解是什么鬼,以及注解的应用场景和如何自定义注解. 下面列举开发中常见的注解 @Override:用于标识 ...

  3. 强化学习实战 | 自定义Gym环境之井字棋

    在文章 强化学习实战 | 自定义Gym环境 中 ,我们了解了一个简单的环境应该如何定义,并使用 print 简单地呈现了环境.在本文中,我们将学习自定义一个稍微复杂一点的环境--井字棋.回想一下井字棋 ...

  4. 强化学习实战 | 自定义Gym环境之扫雷

    开始之前 先考虑几个问题: Q1:如何展开无雷区? Q2:如何计算格子的提示数? Q3:如何表示扫雷游戏的状态? A1:可以使用递归函数,或是堆栈. A2:一般的做法是,需要打开某格子时,再去统计周围 ...

  5. 深入理解Java:注解(Annotation)自定义注解入门

    转载:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准 ...

  6. 【转】深入理解Java:注解(Annotation)自定义注解入门

    http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准的me ...

  7. Java注解(Annotation)自定义注解入门

    要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法. 元注解: 元注解的作用就是负责注解其他注解.Java5. ...

  8. Java:注解(Annotation)自定义注解入门

    转载地址:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的 ...

  9. 注解(Annotation)自定义注解入门

    摘自:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准 ...

随机推荐

  1. ACM-ICPC竞赛模板

    为了方便打印,不再将代码放到代码编辑器里,祝你好运. ACM-ICPC竞赛模板(1) 1. 几何 4 1.1 注意 4 1.2 几何公式 4 1.3 多边形 6 1.4 多边形切割 9 1.5 浮点函 ...

  2. HDU 4064 Carcassonne(插头DP)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4064 Problem Description Carcassonne is a tile-based ...

  3. 一天弹出一次广告cookie

    function setCookie(name, value, expire) { window.document.cookie = name + "=" + escape(val ...

  4. sql存储过程传入ID集合,和临时表的使用

    方式1: Declare @SQL NVarChar(max) set @SQL='select *from Loanee as a  ApplicationID in ('+@Application ...

  5. C# 文件读取(一)

    1. 读写文件的步骤: 创建一个文件流 -- 创建相应的读写器 -- 执行读写操作 -- 关闭读写器 -- 关闭文件流 创建一个文件流:   FileStream objfs = new FileSt ...

  6. SLC、MLC和TLC三者的区别

    SLC=Single-LevelCell,即1bit/cell,速度快寿命长,价格超贵(约MLC3倍以上的价格),约10万次擦写寿命 MLC=Multi-LevelCell,即2bit/cell,速度 ...

  7. zw版【转发·台湾nvp系列Delphi例程】HALCON CheckDifference

    zw版[转发·台湾nvp系列Delphi例程]HALCON CheckDifference unit Unit1;interfaceuses Windows, Messages, SysUtils, ...

  8. 【py分析】使用SGMLParser分析淘宝html

    SGMLParser Python 默认自带 HTMLParser 以及 SGMLParser 等等解析器,前者实在是太难用了,我就用 SGMLParser 写了一个示例程序: import urll ...

  9. linux下在eclipse上运行hadoop自带例子wordcount

    启动eclipse:打开windows->open perspective->other->map/reduce 可以看到map/reduce开发视图.设置Hadoop locati ...

  10. android SDK安装容易出错的原因

    1.实际上,安卓SDK安装之后,拷贝到其他的机子上面.配置一下环境变量,就可以跑起来的 2.但是拷贝到其他的机子上面临着一个问题就是Eclipse已经配置了的android环境,需要在新的机子上面修改 ...