论坛首页 编程语言技术论坛

在 Eclipse 里使用 Java 6 注解处理器

浏览 6175 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-06-29  

 

在 Eclipse 里使用 Java 6 注解处理器

原文:Using Java 6 processors in Eclipse

http://kerebus.com/2011/02/using-java-6-processors-in-eclipse/

 

    我没有找到这方面的完整的教程,所以花费两个小时的时间完成了这个,希望他能够节省你的时间。

    JDK 5 加入了 APT(注解处理工具)。它曾是 SDK 的一部分,但它在非官方的 com.sun.* 包里,而且还必须使用“apt”工具来处理源代码。

    JDK6清理了这些API,并将他们集成到 javac 中,所以现在不必再使用独立的apt工具了。

    显然,在把源代码编译成class文件之前根据注解对他们做一些处理,可以用来做一些很有意思的事情。比如代码生成和于 IDE 无关的代码分析;而且你不必直接使用注解。我猜 JPA2 的 meta-model 在他的标准API中就是使用了这个技术实现的。

    我用 Eclipse 写了一个 java 6 注解处理器的例子。所有的内容都可以集成到 maven 中,但我只是集中精力在怎样在 Eclipse 上实现他。

    所以我们要做个注解处理器,可以用它来对工程中的每个类生成一个新的类。另外,我们再让以 T 字母开头的类显示一个警告。对,这很傻。


第一步:新建一个处理器工程

SillyProcessor.java:

@SupportedAnnotationTypes(value= {"*"})
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class SillyProcessor extends AbstractProcessor { 

	private Filer filer;
	private Messager messager;

	@Override
	public void init(ProcessingEnvironment env) {
		filer = env.getFiler();
		messager = env.getMessager();
	}

	@Override
	public boolean process(Set elements, RoundEnvironment env) {

		for (Element element : env.getRootElements()) {

			if (element.getSimpleName().toString().startsWith("Silly")) {
				// 不要循环为已经生成的类生成新的类
				continue;
			}

			if (element.getSimpleName().toString().startsWith("T")) {
				messager.printMessage(Kind.WARNING,
					"This class name starts with a T!",
					element);
			}

			String sillyClassName = "Silly" + element.getSimpleName();
			String sillyClassContent =
					"package silly;\n"
				+	"public class " + sillyClassName + " {\n"
				+	"	public String foobar;\n"
				+	"}";

			JavaFileObject file = null;

			try {
				file = filer.createSourceFile(
						"silly/" + sillyClassName,
						element);
				file.openWriter()
					.append(sillyClassContent)
					.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}

		return true;
	}
}

    将这个处理器注册到 Eclipse 上,我建立如下 META-INF 文件:

META-INF/services/javax.annotation.processing.Processor:

com.kerebus.annotation.processor.SillyProcessor

    这里只包含了处理器实现类的类名。我不确定你是否可以在这里列出多个处理器。

    就这样。现在导出一个 jar 文件,并且在你需要用到这个处理器的工程上导入这个文件。

第二步:建立一个使用你的处理器的工程

In the properties for your new project go to Java Compiler -> Annotation Processing
Check the “Enable Project Specific Settings” and make sure “Enable annotation processing” is checked. I also changed the generated source directory to a name which didn’t start with a dot so it wouldn’t be hidden in the package explorer (files or directories which start with a dot are by default filtered away in eclipse).

    在工程的属性中找到  Java Compiler -> Annotation Processing 查看 “Enable Project Specific Settings” 确认 “Enable annotation processing” 被选中。为了不让他在包浏览器中隐藏,我还修改了  generated source directory ,去掉了开始的点(Eclipse 会将文件名以点开始的文件或文件夹过滤掉)。

    然后,转到  Java Compiler -> Annotation Processing -> Factory Path 你可以在这里导入处理器的 jar 文件。不可以使用工程引用。

    点击 “Advanced” 按钮,会显示一个对话框,列出了  META-INF/services/javax.annotation.processing.Processor 文件中的内容。选择它并按OK。

第三步:Build!

    完成了。这是在我的工程里显示的样子:

So we get a warning for the Thing class because its class name start with a “T” and for each class in the project we get corresponding “Silly” classes generated. These are compiled and usable just like any other normal class.

    由于 Thing 类是 T 开头,所以有一个警告,并且每一个工程里的类都生成了一个对应的“Silly”类。这些类的编译和使用与其他普通的类一样。

    欲了解更多请参看 eclipse jdt/apt docs, this bit about creating a code analyzer 或者 offical docs

 

 

论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics