2014-11-06 92 views
0

目前我有标准之一:所有类型的AspectJ类型模式都带有属性?

@DeclareParents(value = "(@moody.MyAttribute *)", defaultImpl = MoodyImpl.class) 

这将我的接口+实现添加到任何类@MyAttribute

我想具有此属性和/或具有所有类做到这一点具有该属性的方法。

那么这个类也应该让我的接口+实现:

class MyClass { 
    @MyAttribute 
    public void test() 
    { 
    } 
} 

这可能吗?

回答

1

不,因为@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,该接口没有类级别注释,但是是方法级别的。

享受!

+0

感谢您的其他选择,感谢它!在我的情况下,它可能会重构注释并为我的类创建新的注释,我发现在我的情况下更好的可用性。 – Blub 2014-11-06 13:25:52

+0

请查看我的更新回答。尽管您之前已经接受了我的旧回答,但我发现了您所问的解决方案。我认为新的解决方案更好,并且在构建过程中不需要注释处理阶段。 – kriegaex 2014-11-06 16:49:20

相关问题