java - 捕获方法对象作为建议 AspectJ 中的参数

标签 java aspectj

我需要在执行方法之前执行一些检查,但是我需要通过反射将此方法作为对象获取,并将其作为回调传递给另一个对象。例如:

我有一个 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/

相关文章:

java - Maven + AspectJ - 配置它的所有步骤

java - IntelliJ IDEA Aspectj(Ajc 编译器)在每次 Make 之后加载类需要花费太多时间

java - While 循环与日历交互

java - GNU 的 Java 编译器 (GCJ) 死了吗?

Java自定义注解在调用被注解的方法之前调用其他一些方法

java - 如何使用 AspectJ weaver 自定义 Spring 注解

java - Spring AOP 关于注解 Controller 的建议

java - URL.openStream() 和 HttpResponse.getEntity().getContent() 下载Inputstream的不同文件

java - for循环结构

java - java中的millis字符串格式