不,因为@DeclareParents
和较新的@DeclareMixin
都需要value
参数中的类名称规范。如果我是你,我会重构我的注释,以便只适用于类,而不是方法,然后我的代码将所有注释移动到类。
如果你绝对想保持自己的道路,还有一个选择:由于AspectJ 1.8.2有一个新的annotation processing feature。您可能想要探索该方法并创建一个注释处理器,为每个受影响的类使用带注释的方法创建一个ITD方面。
更新:我刚才想起了非标准的编译器选项-XhasMember
,您可以使用:
ajc -X
AspectJ Compiler 1.8.2 non-standard options:
(...)
-XhasMember allow hasmethod() and hasfield type patterns in
declare parents and declare @type
(...)
警告:这似乎不符合语法@AspectJ,即工作您不能使用注释风格@DeclareParents
,但必须使用本机AspectJ语法declare parents
。默认的接口实现也是不同的,即通过ITD方面,不需要特定的实现类。
这里是一个可编译,完全自洽的代码示例:
标记注解:
package de.scrum_master.app;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
public @interface MyAttribute {}
接口经由ITD实施:
package de.scrum_master.app;
public interface Moody {
public void sayHelloTo(String name);
}
样品带有(out)标记注释的类:
类Foo
在课程级别有注释,Bar
在方法级别,Zot
根本没有注释。
package de.scrum_master.app;
@MyAttribute
public class Foo {
public static void foo() {}
}
package de.scrum_master.app;
public class Bar {
@MyAttribute
public static void bar() {}
}
package de.scrum_master.app;
public class Zot {
public static void zot() {}
}
驱动应用:
出于演示的目的,应用程序检查用于通过反射方法sayHelloTo(String)
的存在。
package de.scrum_master.app;
import java.lang.reflect.Method;
public class Application {
public static void main(String[] args) throws Exception {
Method method;
try {
method = Foo.class.getDeclaredMethod("sayHelloTo", String.class);
} catch (NoSuchMethodException nsme) {
method = null;
}
System.out.println("Foo: " + method);
try {
method = Bar.class.getDeclaredMethod("sayHelloTo", String.class);
} catch (NoSuchMethodException nsme) {
method = null;
}
System.out.println("Bar: " + method);
try {
method = Zot.class.getDeclaredMethod("sayHelloTo", String.class);
} catch (NoSuchMethodException nsme) {
method = null;
}
System.out.println("Zot: " + method);
}
}
控制台输出(无方面):
Foo: null
Bar: null
Zot: null
看点:
package de.scrum_master.aspect;
import de.scrum_master.app.Moody;
import de.scrum_master.app.MyAttribute;
public aspect ITDAspect {
declare parents : @MyAttribute * implements Moody;
declare parents : hasmethod(@MyAttribute * *(..)) implements Moody;
public void Moody.sayHelloTo(String name) {
System.out.println("Hello " + name);
}
}
控制台输出(纵横):
Foo: public void de.scrum_master.app.Foo.sayHelloTo(java.lang.String)
Bar: public void de.scrum_master.app.Bar.sayHelloTo(java.lang.String)
Zot: null
Voilà!我们已经成功地添加了包含其默认实现的接口到Bar
,该接口没有类级别注释,但是是方法级别的。
享受!
感谢您的其他选择,感谢它!在我的情况下,它可能会重构注释并为我的类创建新的注释,我发现在我的情况下更好的可用性。 – Blub 2014-11-06 13:25:52
请查看我的更新回答。尽管您之前已经接受了我的旧回答,但我发现了您所问的解决方案。我认为新的解决方案更好,并且在构建过程中不需要注释处理阶段。 – kriegaex 2014-11-06 16:49:20