捕获方法对象作为建议 AspectJ 中的参数
Capture Method object as parameter in the advice AspectJ
我需要在执行一个方法之前执行一些检查,但我需要通过反射将这个方法作为一个对象获取,然后将其作为回调传递给另一个对象。例如:
我有一个视图控制器,我需要使用特定注释对某些方法进行访问控制。此方法导航到需要通过先前配置的密码进行控制访问的视图。
@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)
将您的方法注释绑定到通知参数,并在切入点中声明该参数及其类型(或直接在内联切入点的通知中)。
你想要的 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
我需要在执行一个方法之前执行一些检查,但我需要通过反射将这个方法作为一个对象获取,然后将其作为回调传递给另一个对象。例如:
我有一个视图控制器,我需要使用特定注释对某些方法进行访问控制。此方法导航到需要通过先前配置的密码进行控制访问的视图。
@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)
将您的方法注释绑定到通知参数,并在切入点中声明该参数及其类型(或直接在内联切入点的通知中)。
你想要的 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