AspectJ构造函数强制工厂模式
我想将对象返回从调用更改为constuctor
从
public class A { public A(){ } public String sayHello() { return "hello"; } public String foo() { return "foo"; } }
至
public class AWrapped extends A { private A wrapped; public AWrapped() { super(); } public AWrapped(A pWrapped) { wrapped=pWrapped; } public String foo() { return wrapped.foo(); } public String sayHello { return "gday mate"; } }
我想要做的是更改从通话返回的对象
A a = new A(); a.sayHello() returns "gday mate"
a是AWrapped的一个实例
我知道这通常是通过工厂模式完成的,但我无法访问A的代码或生成新A的代码。 并且有1000个地方可以创建A.
似乎Aspectj可能会做到这一点,但我不太了解它,如果AspectJ会做的诀窍如何绕过无限包装我需要知道它是从内部和方面构建的所以它不会再次包装它。
谢谢Jon的帮助
如果我理解你,你可以做以下事情:
我创建了三个包:
- 方面的aspectj和AWrapped.java
- A.java未知(也可能是Bytecode但你必须使用加载时间编织 )
- 主要测试
A a = new A();
如果在类A上进行new()
调用,则MyAspect返回AWrapped对象:
package aspectj; import unknown.A; @Aspect public class MyAspect { @Pointcut("call(unknown.A.new(..)) && !within(aspectj..*)") public static void init(ProceedingJoinPoint pjp) { } @Around("init(pjp)") public Object initAdvice(ProceedingJoinPoint pjp) throws Throwable{ Object ret = pjp.proceed(); return new AWrapped((A) ret); } }
用于检测:
package main; import unknown.A; public class Main { public static void main(String[] args) { A a = new A(); System.out.println(a.sayHello()); } }
这输出:
gday mate