我如何使用 AspectJ 访问私有字段?
How do I access private fields with AspectJ?
我正在调查 AspectJ
及其许多用途并发现了 mixins
。
我可以找到许多使用纯 AspectJ
.aj
方面的示例,但是我只需要使用 @AspectJ
注释。
我想要实现的是:-
我有一个无法修改的 class,它有一个私有的 class 变量,我需要在特定的 class 方法完成执行后询问该变量。此 class 没有与此私有 class 变量关联的 getter 或 setter 方法。
public final class CannotAmend {
private Uri privateUri;
public final void methodOne(){}
public final void methodTwo(){}
public final void methodThree(){
privateUri = "something";
}
}
我需要一个 aspect/mixin 可以捕获 @After
methodThree()
并允许我看到 privateUri
中设置的值。
这可以实现吗?
有@AspectJ
个注释?
我在哪里可以找到 documentation/tutorial/examples 如何实现这一点?
不适用于 mixins,但您可以使用 @Around
通知来获取 JoinPoint
并通过反射获取字段。
例如:
@Around("execution(* *.methodThree())")
public Object getValue(ProceedingJoinPoint pjp) throws Throwable {
try {
return pjp.proceed();
} finally {
System.out.println(pjp.getThis().getClass().getDeclaredField("privateUri").get(pjp.getThis()));
}
}
在一个方面内,您可以使用反射访问私有字段 API。
在这方面你需要两件事:
- 用于定义方面匹配的方法的切入点。
- 并且用
@After
注释的方法包含在与切入点 returns 匹配的方法之后执行的逻辑。
@Aspect
public class MyAspect {
@Pointcut("execution(* CannotAmend.methodThree(..))")
public void methodThreePointcut(){
}
@After("methodThreePointcut()")
public void afterMethod(JoinPoint joinPoint) throws NoSuchFieldException, IllegalAccessException {
Object instance = joinPoint.getThis();
Field privateUriField = instance.getClass().getDeclaredField("privateUri");
privateUriField.setAccessible(true);
String privateUri = (String) privateUriField.get(instance);
System.out.println(privateUri); // prints "something"
}
}
附带说明一下,使用字符串常量访问私有字段并不是一个干净的解决方案。如果将来某个时候变量的名称发生变化或者它被删除,方面将会中断。
我正在调查 AspectJ
及其许多用途并发现了 mixins
。
我可以找到许多使用纯 AspectJ
.aj
方面的示例,但是我只需要使用 @AspectJ
注释。
我想要实现的是:-
我有一个无法修改的 class,它有一个私有的 class 变量,我需要在特定的 class 方法完成执行后询问该变量。此 class 没有与此私有 class 变量关联的 getter 或 setter 方法。
public final class CannotAmend {
private Uri privateUri;
public final void methodOne(){}
public final void methodTwo(){}
public final void methodThree(){
privateUri = "something";
}
}
我需要一个 aspect/mixin 可以捕获 @After
methodThree()
并允许我看到 privateUri
中设置的值。
这可以实现吗?
有@AspectJ
个注释?
我在哪里可以找到 documentation/tutorial/examples 如何实现这一点?
不适用于 mixins,但您可以使用 @Around
通知来获取 JoinPoint
并通过反射获取字段。
例如:
@Around("execution(* *.methodThree())")
public Object getValue(ProceedingJoinPoint pjp) throws Throwable {
try {
return pjp.proceed();
} finally {
System.out.println(pjp.getThis().getClass().getDeclaredField("privateUri").get(pjp.getThis()));
}
}
在一个方面内,您可以使用反射访问私有字段 API。
在这方面你需要两件事:
- 用于定义方面匹配的方法的切入点。
- 并且用
@After
注释的方法包含在与切入点 returns 匹配的方法之后执行的逻辑。
@Aspect
public class MyAspect {
@Pointcut("execution(* CannotAmend.methodThree(..))")
public void methodThreePointcut(){
}
@After("methodThreePointcut()")
public void afterMethod(JoinPoint joinPoint) throws NoSuchFieldException, IllegalAccessException {
Object instance = joinPoint.getThis();
Field privateUriField = instance.getClass().getDeclaredField("privateUri");
privateUriField.setAccessible(true);
String privateUri = (String) privateUriField.get(instance);
System.out.println(privateUri); // prints "something"
}
}
附带说明一下,使用字符串常量访问私有字段并不是一个干净的解决方案。如果将来某个时候变量的名称发生变化或者它被删除,方面将会中断。