我的意思是,我试图使用注释来做以下代码
@Anno1(Argument = "Option1") public class TestClass { @Anno2 public void test() { } }
成
public class TestClass { private static StaticReference z; public void test() { z.invokeToAll(); } }
这是一个非常简单的例子,我正在努力做. Anno1将有很多可能的组合,但这不是我的问题.我的问题是如何添加代码到方法test()
如果可能,我正在寻找一个更通用的解决方案.例如.一种在方法中添加各种代码的方法(不仅仅是一种方式.invokeToAll())
到目前为止,我使用import javax.annotation.processing.*;我有以下代码,但我不知道如何从那里继续
private void processMethodAnnotations(RoundEnvironment env) { for (Element e : env.getElementsAnnotatedWith(Anno2.class)) { //If it is a valid annotation over a method if (e.getKind() == ElementKind.METHOD) { //What to do here :S }else { processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,"Not a method!",e); } } }
我发现了一些有关Java反思的内容,但是我没有找到任何来源来帮助我.
显然我在我的代码中扩展了AbstractProcessor
我已经找到这个教程(http://www.zdnetasia.com/writing-and-processing-custom-annotations-part-3-39362483.htm)但是这关系到创建一个新的类,而不仅仅是改变一个方法.而javax.lang.model.elements不提供任何编辑该元素的方式(在我的例子中代表一个方法).
我希望我的问题是明确的,符合规则.如果没有,请评论,我会澄清.谢谢.
解决方法
When Java source code is compiled,
annotations can be processed by
compiler plug-ins called annotation
processors. Processors can produce
informational messages or create
additional Java source files or
resources,which in turn may be
compiled and processed,but annotation
processors cannot modify the annotated
code itself.
人们建议你正确的方法 – AOP.具体可以使用AspectJ. “快速结果”的方式是(如果使用Eclipse):
1)安装AJDT(AspectJ开发工具)
2)创建AspectJ项目并添加您的类和注释
3)创建方面:
public aspect Processor { private StaticReference z; pointcut generic() // intercept execution of method named test,annotated with @Anno1 // from any class type,annotated with @Anno2 : execution(@Anno2 * (@Anno1 *).test()) // method takes no arguments && args (); // here you have write what you want method actually does void around () : generic() { z.invokeToAll(); } }
现在你可以执行测试,你会看到它的工作原理;)AJDT自动编译代码,所以不需要任何手工工作,希望这就是你所说的“魔术”;)
更新:
如果你在test()方法中的代码取决于Anno1注释值,那么在内部方面你可以通过这种方式获得它执行的类注释:
void around () : generic() { Annotation[] classAnnotations = thisJoinPoint.getThis().getClass().getAnnotations(); String ArgumentValue = null; for ( Annotation annotation : classAnnotations ) { if ( annotation instanceof Anno1 ) { ArgumentValue = ((Anno1) annotation).Argument(); break; } } if ( ArgumentValue != null && ArgumentValue.equals("Option1")) { z.invokeToAll(); } }
其中thisJoinPoint是一个特殊的参考变量.
UPDATE2:
如果要在您的方面添加System.out.println(this),则需要在其中写入System.out.println(thisJoinPoint.getThis()),刚刚测试并可以正常工作. thisJoinPoint.getThis()返回你“这个”但不完全;实际上这是Object变量,如果你想获得任何属性,你需要投射或使用反射.而这个JoinPoint.getThis()不提供对私有属性的访问.
嗯,现在好像你的问题已经回答了,但是如果我错过任何东西,或者你以这种方式获得更多的问题/问题,请随时问;)