java - AspectJ 类型模式适用于所有具有属性的方法的类型?

标签 java aop aspectj

目前我有标准的:

@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/

相关文章:

java - 如何从 Java 运行 ajc?

java - Android Things 和 Adafruit Ultimate GPS Breakout v3

java - 如何从 XML Spring 调度配置到注解/代码配置?

java - Struts2 有没有办法将元数据添加到 struts.xml 文件中的操作定义中?

java - 如何为java自定义注释提供属性占位符支持

java - 编译时编织配置

java - 如何获取带注解的方法参数和他的注解

maven-2 - maven cobertura 报告 0% 与 aspectj

java - 生成强大团队的最佳算法

java - 由于名称未定义,AspectJ 的构建任务失败