我需要在执行方法之前执行一些检查,但是我需要通过反射将此方法作为对象获取,并将其作为回调传递给另一个对象。例如:
我有一个 View Controller ,我需要使用特定注释对某些方法进行访问控制。此方法导航到需要通过先前配置的密码控制访问的 View 。
@AccessControl(accessID = "bookKeysViewId")
private void navigateToBookKeys() {
navigateTo(ControllerPasswordBookKey.class);
}
在执行该方法之前,我需要检查访问权限。例如:
pointcut makeAccessControl() : execution(@AccessControl * *(..));
before() : makeAccessControl(){
Method method = // any way to get the intercepted method
String idAccess = // get de access id from method annotation
EnumTypeAccess typeAccess = ManagerAccess.checkAccess(idAccess);
switch (typeAccess ){
case NEEDED: openPasswordDialog();break; // wrong password ? throw an exception and interrupt the method execution.
case NEED_CONFIG: // create configuration view, pass "method" as callback and navigate to it
}
}
最佳答案
让我们看看这个小MCVE :
标记注释:
package de.scrum_master.app;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(METHOD)
public @interface AccessControl {
String accessID();
}
驱动程序应用程序:
package de.scrum_master.app;
public class Application {
public void doSomething() {
navigateToBookKeys();
}
@AccessControl(accessID = "bookKeysViewId")
private void navigateToBookKeys() {}
public static void main(String[] args) {
new Application().doSomething();
}
}
方面:
您可以通过 @annotation(accessControl)
将方法注释绑定(bind)到通知参数并在切入点中声明该参数及其类型(或直接在内联切入点的建议中声明)。
Method
您想要的对象(无论出于何种原因)都可以通过 ((MethodSignature) thisJoinPoint.getSignature()).getMethod()
获得.
package de.scrum_master.aspect;
import java.lang.reflect.Method;
import org.aspectj.lang.reflect.MethodSignature;
import de.scrum_master.app.AccessControl;
public aspect AccessControlAspect {
pointcut makeAccessControl(AccessControl accessControl) :
@annotation(accessControl) &&
execution(* *(..));
before(AccessControl accessControl) : makeAccessControl(accessControl) {
Method method = ((MethodSignature) thisJoinPoint.getSignature()).getMethod();
String accessID = accessControl.accessID();
System.out.println(thisJoinPoint);
System.out.println(" method = " + method);
System.out.println(" accessID = " + accessID);
}
}
控制台日志:
execution(void de.scrum_master.app.Application.navigateToBookKeys())
method = private void de.scrum_master.app.Application.navigateToBookKeys()
accessID = bookKeysViewId
关于java - 捕获方法对象作为建议 AspectJ 中的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57299686/