前言

每当采取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了。
图片 1

与此同时我们得扣押一下变动的jar里面都起啊东西:
图片 2

测试

今天我们用测试一下转移的jar包是不是要是预期会出口信息。将AnnotationProcessorTest.jar拷贝置一个测试项目的libs,然后于肆意选择几单位置用PrintMe修饰:
图片 3
图片 4

兹编译测试项目,在输出console了照观察日志
图片 5

参考

  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

相关文章

网站地图xml地图