目前我有标准的:
@DeclareParents(value = "(@moody.MyAttribute *)", defaultImpl = MoodyImpl.class)
这会将我的接口(interface)+实现添加到任何带有@MyAttribute
的类
我想对具有此属性和/或具有具有该属性的方法的所有类执行此操作。
所以这个类也应该得到我的接口(interface)+实现:
class MyClass {
@MyAttribute
public void test()
{
}
}
这可能吗?
最佳答案
不,因为 @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
但必须使用 native AspectJ 语法 declare parents
。默认的接口(interface)实现也是不同的,即通过方面的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 实现的接口(interface):
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
瞧!我们已成功将接口(interface)(包括其默认实现)添加到 Bar
它没有类级注释,而是方法级注释。
享受吧!
关于java - AspectJ 类型模式适用于所有具有属性的方法的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26777341/