可以使用AOP框架将注释添加到方法或成员中吗?

时间:2016-07-18 04:09:38

标签: java aop

我可以使用AOP(AspectJ,Guice或其他)向我无法修改的类添加注释吗?我的第一个用例是添加持久性和绑定注释。我知道我可以为JPA和JAXB编写XML配置文件,但我不知道为JSON绑定做任何方法。

我已经找了一些示例/教程,但没有找到任何证明这一点的东西。是否有可能,如果是这样,有人可以提供一个好的例子或更好的指向我一些资源吗?

1 个答案:

答案 0 :(得分:0)

是的,您可以将AspectJ用于此目的(引用AspectJ cheat sheet,另请参阅AspectJ Development Kit Developer's Notebook):

  • declare @type: C : @SomeAnnotation;
    在类型@SomeAnnotation上声明注释C
  • declare @method: * C.foo*(..) : @SomeAnnotation;
    声明@SomeAnnotation中以C开头的foo中声明的所有方法的注释declare @constructor: C.new(..) : @SomeAnnotation;
  • @SomeAnnotation
    C
  • 中声明的所有构造函数上声明注释declare @field: * C.* : @SomeAnnotation;
  • @SomeAnnotation
    C
  • 中声明的所有字段上声明注释@Inherited

以防您想问:此功能仅在本机AspectJ语法中支持,而不是在注释样式的@AspectJ语法中支持。

更新:以下是一些显示

的示例代码
  • 如何向类,接口和方法添加注释,
  • 即使标记为+的注释也只是从类继承到子类,从不从接口继承到类,也从不继承子类方法(许多开发人员不知道的典型Java警告,请参阅Emulate annotation inheritance for interfaces and methods with AspectJ解释和可能的解决方法),
  • 如何通过AspectJ仍然可以通过MyInterface+子类说明符将注释应用于实现接口的类,例如:在declare @type
  • 另一方面如何能够立即查看和使用通过declare @methodpackage de.scrum_master.app; public interface MyInterface { void doSomething(); int doSomethingElse(int a, int b); String sayHelloTo(String name); } 等添加的注释。

类层次结构,包括抽象基类和接口:

package de.scrum_master.app;

public abstract class NormalBase implements MyInterface {
    @Override
    public abstract void doSomething();

    @Override
    public int doSomethingElse(int a, int b) {
        return a + b;
    }

    @Override
    public abstract String sayHelloTo(String name);
}
package de.scrum_master.app;

public class Normal extends NormalBase {
    @Override
    public void doSomething() {
        //System.out.println("Doing something normal");
    }

    @Override
    public String sayHelloTo(String name) {
        return "A normal hello to " + name;
    }

    public void doNothing() {
        //System.out.println("Being lazy in a normal way");
    }
}
package de.scrum_master.app;

public abstract class SpecialBase {
    public abstract void doFoo();
    public abstract void makeBar();
}
package de.scrum_master.app;

public class Special extends SpecialBase implements MyInterface {
    @Override
    public void doSomething() {
        //System.out.println("Doing something special");
    }

    @Override
    public int doSomethingElse(int a, int b) {
        return a * b;
    }

    @Override
    public String sayHelloTo(String name) {
        return "A special hello to " + name;
    }

    @Override
    public void doFoo() {
        //System.out.println("Doing foo");
    }

    @Override
    public void makeBar() {
        //System.out.println("Making bar");
    }

    public int doZot() {
        return 11;
    }

    public String makeBlah() {
        return "Blah";
    }
}
package de.scrum_master.app;

public class SpecialTwo extends SpecialBase {
    @Override
    public void doFoo() {
        //System.out.println("Doing foo");
    }

    @Override
    public void makeBar() {
        //System.out.println("Making bar");
    }

    public String doXxx() {
        return "Xxx";
    }

    public int makeBlah() {
        return 22;
    }
}
package de.scrum_master.app;

public class Application {
    public static void main(String[] args) {
        System.out.println("Normal instance");
        Normal normal = new Normal();
        normal.doSomething();
        normal.doSomethingElse(3, 5);
        normal.sayHelloTo("John");
        normal.doNothing();

        System.out.println("\nNormal instance as NormalBase");
        NormalBase normalBase = normal;
        normalBase.doSomething();
        normalBase.doSomethingElse(3, 5);
        normalBase.sayHelloTo("John");

        System.out.println("\nNormal instance as MyInterface");
        MyInterface myInterface = normal;
        myInterface.doSomething();
        myInterface.doSomethingElse(3, 5);
        myInterface.sayHelloTo("John");

        System.out.println("\nSpecial instance");
        Special special = new Special();
        special.doSomething();
        special.doSomethingElse(7, 8);
        special.doFoo();
        special.doZot();
        special.makeBar();
        special.makeBlah();
        special.sayHelloTo("Jane");

        System.out.println("\nSpecial instance as SpecialBase");
        SpecialBase specialBase = special;
        specialBase.doFoo();
        specialBase.makeBar();

        System.out.println("\nSpecial instance as MyInterface");
        myInterface = special;
        myInterface.doSomething();
        myInterface.doSomethingElse(7, 8);
        myInterface.sayHelloTo("Jane");

        System.out.println("\nSpecialTwo instance");
        SpecialTwo specialTwo = new SpecialTwo();
        specialTwo.doFoo();
        specialTwo.makeBar();
        specialTwo.makeBlah();
        specialTwo.doXxx();

        System.out.println("\nSpecialTwo instance as SpecialBase");
        specialBase = specialTwo;
        specialBase.doFoo();
        specialBase.makeBar();
    }
}

驱动程序应用程序创建各种对象,调用各种方法:

package de.scrum_master.app;

import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface InterfaceMarker {}

稍后某些标记注释将按方面添加到接口,类,方法中

package de.scrum_master.app;

import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ClassMarker {}
package de.scrum_master.app;

import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MethodMarker {}
package de.scrum_master.aspect;

import de.scrum_master.app.ClassMarker;
import de.scrum_master.app.InterfaceMarker;
import de.scrum_master.app.MethodMarker;
import de.scrum_master.app.MyInterface;
import de.scrum_master.app.SpecialBase;

public aspect AnnotationGenerator {
    declare @type : MyInterface+ : @InterfaceMarker;
    declare @type : SpecialBase : @ClassMarker;
    declare @method : * say*(..) : @MethodMarker;
}

方面为界面,类,方法添加注释:

package de.scrum_master.aspect;

import de.scrum_master.app.ClassMarker;
import de.scrum_master.app.InterfaceMarker;
import de.scrum_master.app.MethodMarker;

public aspect MarkedObjectLogger {
    before() : @annotation(InterfaceMarker) {
        System.out.println(thisJoinPoint + " -> @InterfaceMarker");
    }

    before() : @annotation(ClassMarker) {
        System.out.println(thisJoinPoint + " -> @ClassMarker");
    }

    before() : @annotation(MethodMarker) && execution(* *(..)) {
        System.out.println(thisJoinPoint + " -> @MethodMarker");
    }
}

Aspect记录已注释类的初始化和带注释方法的执行:

Normal instance
staticinitialization(de.scrum_master.app.NormalBase.<clinit>) -> @InterfaceMarker
staticinitialization(de.scrum_master.app.Normal.<clinit>) -> @InterfaceMarker
execution(String de.scrum_master.app.Normal.sayHelloTo(String)) -> @MethodMarker

Normal instance as NormalBase
execution(String de.scrum_master.app.Normal.sayHelloTo(String)) -> @MethodMarker

Normal instance as MyInterface
execution(String de.scrum_master.app.Normal.sayHelloTo(String)) -> @MethodMarker

Special instance
staticinitialization(de.scrum_master.app.SpecialBase.<clinit>) -> @ClassMarker
staticinitialization(de.scrum_master.app.Special.<clinit>) -> @InterfaceMarker
staticinitialization(de.scrum_master.app.Special.<clinit>) -> @ClassMarker
execution(String de.scrum_master.app.Special.sayHelloTo(String)) -> @MethodMarker

Special instance as SpecialBase

Special instance as MyInterface
execution(String de.scrum_master.app.Special.sayHelloTo(String)) -> @MethodMarker

SpecialTwo instance
staticinitialization(de.scrum_master.app.SpecialTwo.<clinit>) -> @ClassMarker

SpecialTwo instance as SpecialBase

控制台日志:

+

尝试从declare @type : MyInterface+中删除@InterfaceMarker并查看提及flow_from_clientsecrets()的所有日志行如何消失,因为实现类不会继承接口注释。