AspectJ类型模式是否适用于具有属性的方法的所有类型? [英] AspectJ type pattern for all types with a method with an attribute?
问题描述
目前,我有标准配置:
@DeclareParents(value = "(@moody.MyAttribute *)", defaultImpl = MoodyImpl.class)
这会将我的界面+实现添加到具有 @MyAttribute
This will add my interface+implementation to any class with @MyAttribute
我想对所有具有此属性和/或具有该属性的方法的类执行此操作.
I would like to do this for all classes that have this attribute AND/OR have a method with that attribute.
所以这个类也应该获得我的界面+实现:
So this class should also get my interface+implementation:
class MyClass {
@MyAttribute
public void test()
{
}
}
有可能吗?
推荐答案
否,因为 @DeclareParents
和较新的 @DeclareMixin
都需要在其值
参数.如果您是我,我将重构注解,使其仅适用于类,而不适用于方法,然后将代码也将所有注解也移至类.
No, because both @DeclareParents
and the newer @DeclareMixin
need class name specifications in their value
parameter. If I were you I would refactor my annotation so as to only be applicable to classes, not methods, and then my code to move all annotations to classes as well.
如果您绝对想坚持自己的想法,还有一个选择:从AspectJ 1.8.2开始,有一个新的
One more option if you absolutely want to stay on your path: Since AspectJ 1.8.2 there is a new annotation processing feature. You might want to explore that one and create an annotation processor creating an ITD aspect for each affected class with annotated methods.
更新:我刚刚记得一个可以使用的非标准编译器选项 -XhasMember
:
Update: I have just remembered a non-standard compiler option -XhasMember
which you can use:
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父母
.默认接口的实现方式也有所不同,即在该方面通过ITD,不需要特定的实现类.
Caveat: It does not seem to work with @AspectJ syntax, i.e. you cannot use annotation-style @DeclareParents
but have to use native AspectJ syntax declare parents
. The default interface implementation is also done differently, i.e. via ITD in the aspect, there is no need for a specific implementation class.
这是一个可编译的,完全自洽的代码示例:
Here is a compileable, fully self-consistent code sample:
标记注释:
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);
}
带有(未)标记注释的类示例:
类 Foo
在类级别具有注释,在方法级别的 Bar
具有注释,而 Zot
则完全没有注释.
Class Foo
has the annotation at class level, Bar
at method level and Zot
has no annotation at all.
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)
的存在.
For demonstration purposes, the application checks for the existence of a method sayHelloTo(String)
via reflection.
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
中,该接口没有类级别的注释,而是方法级别的注释.
Voilà! We have successfully added the interface including its default implementation to Bar
which does not have class-level annotation, but a method-level one.
享受!
这篇关于AspectJ类型模式是否适用于具有属性的方法的所有类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!