Java中注释处理的缺点? [英] The drawbacks of annotation processing in Java?

查看:152
本文介绍了Java中注释处理的缺点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在考虑启动一个用于使用注释在Java中生成代码的项目(我不会详细说明,因为它并不真正相关)。我想知道该项目的有效性和实用性,令我印象深刻的是依赖于Annontation Processor Tool(apt)。



我想要什么要知道,因为我不能从经验中说出,在Java中使用注释处理的缺点是什么?



这些可能是任何东西,包括以下内容: / p>


  • 编写处理器时很难做TDD

  • 很难将处理包括在内构建系统

  • 处理需要很长时间,并且很难让它快速运行

  • 使用IDE中的注释需要每个插件,以使其在报告错误时表现相同



这些只是示例,而不是我的意见。我正在研究是否有任何这些是真的(包括问这个问题;-))



我确信必定有缺点(例如, Qi4J 特别列出不使用预处理器作为优势)但我没有经验用它来说明什么它们是。



使用注释处理的合理替代方法可能是为相关的IDE创建插件以生成代码(它可能类似于覆盖/实现方法功能,可以生成没有方法体的所有签名)。但是,每次代码的相关部分发生变化时,都必须重复该步骤,据我所知,注释处理不会重复。



关于示例考虑到入侵量的注释,我不认为使用需要类似的东西,对于任何给定的类可能是少数。这当然不能阻止它被滥用。

解决方案

我创建了一组JavaBean注释( http://code.google.com/p/javadude/wiki/Annotations



[注意:我现在正在开发新版本,因此中继代码与更新网站下载不匹配]



测试



测试它们可能非常有用......



我通常通过在eclipse中使用测试代码创建项目并构建它来接近它,然后制作副本并关闭注释处理。



然后我可以使用Eclipse来将活动测试项目与项目的预期副本进行比较。



我还没有太多的测试用例(生成这么多项目非常繁琐)属性的组合),但这有帮助。



构建系统



我们在构建系统中注释实际上非常容易。请参阅 http://code.google.com/p/javadude/wiki/Annotations 有关如何在ant脚本中使用它并在eclipse中使用它的示例,只需要创建一个插件来指定注释处理器扩展并在想要使用它的项目中启用注释处理。



我在连续构建环境中使用了注释处理,构建了注释&处理器,然后在构建的其余部分使用它。这真的很无痛。



处理时间



我还没有找到这个成为一个问题 - 小心你在处理器中做了什么。我在我的代码中生成了很多代码,运行正常。它在ant中有点慢。



请注意,Java6处理器可以运行得更快,因为它们是正常编译过程的一部分。但是,我无法让它们在代码生成能力方面正常工作(我认为很多问题是eclipse的支持和运行多阶段编译)。现在,我坚持使用Java 5.



错误处理



这是注释API中经过深思熟虑的事情之一。 API有一个messenger对象,可以处理所有错误。每个IDE都提供了一个实现,可以将其转换为代码中正确位置的相应错误消息。



我唯一特定的eclipse就是强制转换处理环境对象所以我可以检查它是作为构建运行还是编辑器协调。如果编辑,我退出。最后我会将其更改为仅在编辑时进行错误检查,以便在您键入时报告错误。但是要小心 - 你需要保持真正快速在对帐期间使用或编辑变得迟钝。



代码生成陷阱



[每条评论增加一点]



注释处理器规范说明你是不允许修改包含注释的类。我怀疑这是为了简化处理(进一步的轮次不需要包含带注释的类,也可以防止无限更新循环)



可以然而,生成其他类,他们建议采用这种方法。



我为所有get / set方法和我需要生成的任何其他方法生成一个超类。我还让处理器验证带注释的类是否扩展了生成的类。例如:

  @Bean(...)
公共类Foo扩展FooGen

我在同一个包中生成一个类,带有带注释类的名称加上Gen,并验证带注释的类是否声明为扩展它。



我看到有人使用编译器树api来修改带注释的类 - 这是违反规范的,我怀疑它们会在某个时刻插入那个洞,所以它赢了工作。



我建议生成一个超类。



整体



我很高兴使用注释处理器 。非常精心设计,特别是关注IDE /命令行构建独立性。



现在,如果您正在进行代码生成,我建议您坚持使用Java5注释处理器 - 你需要运行一个名为apt的独立工具来处理它们,然后进行编译。



请注意,Java 5和Java 6注释处理器的API是不同的! Java 6处理API是更好的恕我直言,但我只是没有运气的java 6处理器做我需要的。



当Java 7出来时我会给新的处理方法另一个镜头。



如果您有任何疑问,请随时给我发电子邮件。 (scott@javadude.com)



希望这会有所帮助!


I am considering starting a project which is used to generate code in Java using annotations (I won't get into specifics, as it's not really relevant). I am wondering about the validity and usefulness of the project, and something that has struck me is the dependence on the Annontation Processor Tool (apt).

What I'd like to know, as I can't speak from experience, is what are the drawbacks of using annotation processing in Java?

These could be anything, including the likes of:

  • it is hard to do TDD when writing the processor
  • it is difficult to include the processing on a build system
  • processing takes a long time, and it is very difficult to get it to run fast
  • using the annotations in an IDE requires a plugin for each, to get it to behave the same when reporting errors

These are just examples, not my opinion. I am in the process of researching if any of these are true (including asking this question ;-) )

I am sure there must be drawbacks (for instance, Qi4J specifically list not using pre-processors as an advantage) but I don't have the experience with it to tell what they are.

The ony reasonable alternative to using annotation processing is probably to create plugins for the relevant IDEs to generate the code (it would be something vaguely similar to override/implement methods feature that would generate all the signatures without method bodies). However, that step would have to be repeated each time relevant parts of the code changes, annotation processing would not, as far as I can tell.

In regards to the example given with the invasive amount of annotations, I don't envision the use needing to be anything like that, maybe a handful for any given class. That wouldn't stop it being abused of course.

解决方案

I've created a set of JavaBean annotations (http://code.google.com/p/javadude/wiki/Annotations)

[Note: I'm working on a new version right now, so the trunk code doesn't match the update site downloads]

Testing

Testing them can be quite trying...

I usually approach it by creating a project in eclipse with the test code and building it, then make a copy and turn off annotation processing.

I can then use Eclipse to compare the "active" test project to the "expected" copy of the project.

I don't have too many test cases yet (it's very tedious to generate so many combinations of attributes), but this is helping.

Build System

Using annotations in a build system is actually very easy. Take a look at http://code.google.com/p/javadude/wiki/Annotations for an example of how it's used in an ant script, and using it in eclipse is just a matter of making a plugin specifying the annotation processor extension and turning on annotation processing in projects that want to use it.

I've used annotation processing in a continuous build environment, building the annotations & processor, then using it in the rest of the build. It's really pretty painless.

Processing Time

I haven't found this to be an issue - be careful of what you do in the processors. I generate a lot of code in mine and it runs fine. It's a little slower in ant.

Note that Java6 processors can run a little faster because they are part of the normal compilation process. However, I've had trouble getting them to work properly in a code generation capacity (I think much of the problem is eclipse's support and running multiple-phase compiles). For now, I stick with Java 5.

Error Processing

This is one of the best-thought-through things in the annotation API. The API has a "messenger" object that handles all errors. Each IDE provides an implementation that converts this into appropriate error messages at the right location in the code.

The only eclipse-specific thing I did was to cast the processing environment object so I could check if it was bring run as a build or for editor reconciliation. If editing, I exit. Eventually I'll change this to just do error checking at edit time so it can report errors as you type. Be careful, though -- you need to keep it really fast for use during reconciliation or editing gets sluggish.

Code Generation Gotcha

[added a little more per comments]

The annotation processor specifications state that you are not allowed to modify the class that contains the annotation. I suspect this is to simplify the processing (further rounds do not need to include the annotated classes, preventing infinite update loops as well)

You can generate other classes, however, and they recommend that approach.

I generate a superclass for all of the get/set methods and anything else I need to generate. I also have the processor verify that the annotated class extends the generated class. For example:

@Bean(...)
public class Foo extends FooGen

I generate a class in the same package with the name of the annotated class plus "Gen" and verify that the annotated class is declared to extend it.

I have seen someone use the compiler tree api to modify the annotated class -- this is against spec and I suspect they'll plug that hole at some point so it won't work.

I would recommend generating a superclass.

Overall

I'm really happy using annotation processors. Very well designed, especially looking at IDE/command-line build independence.

For now, I would recommend sticking with the Java5 annotation processors if you're doing code generation - you need to run a separate tool called apt to process them, then do the compilation.

Note that the API for Java 5 and Java 6 annotation processors is different! The Java 6 processing API is better IMHO, but I just haven't had luck with java 6 processors doing what I need yet.

When Java 7 comes out I'll give the new processing approach another shot.

Feel free to email me if you have questions. (scott@javadude.com)

Hope this helps!

这篇关于Java中注释处理的缺点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆