Java 6 - 注解处理器和代码添加
我编写了一个包含属性和 AnnotationProcessor 元数据的自定义注释:
@SupportedAnnotationTypes({"<package>.Property"})
public class PropertyProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
// Get messager object
Messager messager = processingEnv.getMessager();
// Iterate through the annotations
for(TypeElement typeElement : annotations) {
// Iterate through the annotated elements
for(Element element : roundEnv.getElementsAnnotatedWith(typeElement)) {
// Get Property annotation
Property property = element.getAnnotation(Property.class);
}
}
return false;
}
}
问题是,我以前使用过 Javassist,但它取决于类加载器,我认为它不适合 OSGi 应用程序。我想在编译带有 Property
注释的类时更改生成的字节码。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您是否尝试过 Google Guice?
Google Guice 允许您通过拦截方法进行一些面向方面的编程。如果这就是您需要做的全部,您可以实现一个 MethodInterceptor,它可以让您在运行时重写方法。它对于隔离横切关注点来说确实非常好。
例如,假设您想阻止某些方法在周末执行,您可以这样注释它们:
定义一个 MethodInterceptor:
然后将拦截器绑定到注释:
Have you tried Google Guice?
Google Guice lets you do a bit of Aspect Oriented Programming by intercepting methods. If that's all you need to do, you can implement a MethodInterceptor that'll let you override methods at runtime. It's really neat for isolating cross-cutting concerns.
For example, lets say you want to prevent a certain methods from being executed on weekends, you can annotate them as so:
Define a MethodInterceptor:
And then bind the interceptor to the annotation:
简短的答案是:您不应该在注释处理期间更改源代码。
我最近遇到了一种情况,这个答案并不令人满意(请参阅 这个问题)。我的解决方案是使用内部 javac api 以编程方式添加我需要的代码。请参阅我对自己问题的回答 了解详情。
我从 Project Lombok 中获得了灵感,从他们的源代码开始,扔掉了我不需要的所有东西。我认为您不会找到更好的起点。
顺便说一句,Javassist 可能不会有帮助,因为您正在处理源树,而不是字节代码。如果您想使用字节码操作库,您可以在编译后静态地执行此操作,也可以在加载类时动态地执行此操作,但不能在注释处理期间执行此操作,因为这是预编译步骤。
The short answer is: you're not supposed to change source code during annotation processing.
I have had a situation recently where that answer was not satisfactory (see this question). My solutions was to programmatically add the code I needed using the internal javac api. See my answer to my own question for details.
I took the inspiration to this from Project Lombok, starting out with their source code and throwing away everything I didn't need. I don't think you'll find a much better starting point.
BTW, Javassist probably won't help, because you are dealing with a source tree, not with byte code. If you want to use a byte code manipulation library you can do that either statically after compiling or dynamically when loading the classes, but not during annotation processing, because that's a pre-compile step.
注释处理并不意味着改变现有的类 - 它只是为了生成额外的代码/资源(在逐类的基础上,否则仅在重新编译修改后的源时会遇到麻烦)。
不久前,我尝试使用 Spoon 来解决类似的问题:我非常喜欢程序处理器的想法(以及 IDE 集成更多),但当时它并不是很稳定...
根据您的用例,AOP 工具(例如: AspectJ) 比 Spoon 更适合您,而且 - 当然 - 您始终可以使用源代码生成器或实现成熟的 DSL(看看神奇的 Xtext)。
根据团队成员的规模、人员流动率和“智力惰性”,您可能会更好地承受普通 Java 的痛苦,而不是引入新工具/技术、组建同事并将新工具集成到您的团队中。持续集成系统。仔细权衡成本/收益。
Annotation processing is not meant to alter existing classes - it is just for generating additional code/resources (on a class-by-class basis, otherwise you'll run into trouble when re-compiling the modified sources only).
Some time ago I tried Spoon for a similar problem: I liked the idea of a program processor very much (and the IDE integration even more), but it was not really stable at the time...
Depending on your use case, an AOP tool (eg: AspectJ) could suite you better than Spoon, and - of course - you could always use a source code generator or implement a full-blown DSL (take a look at the fantastic Xtext).
Depending on the size, turnover rate and "intellectual inertia" of your team mates - you could be better off bearing the pains of plain java instead of those of introducing a new tool/technology, forming co-workers and integrating the new tool in your CI system. Weigh costs/benefits carefully.