我可以使用AOP(AspectJ,Guice或其他)向我无法修改的类添加注释吗?我的第一个用例是添加持久性和绑定注释。我知道我可以为JPA和JAXB编写XML配置文件,但我不知道为JSON绑定做任何方法。
我已经找了一些示例/教程,但没有找到任何证明这一点的东西。是否有可能,如果是这样,有人可以提供一个好的例子或更好的指向我一些资源吗?
答案 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解释和可能的解决方法),MyInterface+
子类说明符将注释应用于实现接口的类,例如:在declare @type
,declare @method
,package 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()
的所有日志行如何消失,因为实现类不会继承接口注释。