java - 使用 AspectJ 更改对象属性

标签 java aop aspectj

是否可以拦截对象方法调用并修改当时的对象属性?

到目前为止我所拥有的

@Pointcut("execution(* java.net.HttpURLConnection.setRequestProperty(..))")
public void connectMethodCall() {
}

@Around("connectMethodCall()")
public Object onGetUrlConnection(ProceedingJoinPoint pjp) throws Throwable {
    HttpURLConnection connection = (HttpURLConnection) pjp.proceed();
    connection.setRequestProperty("header key", "header value");
    return pjp.proceed();
}

我想在这个示例中设置连接 header 并将对象返回到执行点。编织是在编译时完成的。我尝试在此之后记录 header ,但我在 @Around 建议中没有设置 header 。也不会引发任何错误。

最佳答案

如果我正确理解这个问题,关于如何获取 target 对象实例的后续问题的答案很简单:只需使用 target() 参数绑定(bind)。快速浏览 AspectJ documentation会向你展示这一点,例如关于 pointcut parameters 的部分。我确实相信这比在这里提问要容易得多,而且耗时更少(也因为必须等待答案)。但无论如何,这是一个开发者互相帮助的地方。那么我们开始吧:

忽略您的 MVCE 示例代码对 Google API 没有执行任何有意义的操作这一事实,我们只需添加一行诊断输出来验证该方面是否确实添加了请求参数:

// (...)
      urlConnection.connect();

      // Just in order to check if the property has indeed been set in the aspect
      System.out.println(urlConnection.getRequestProperty("From"));

      OutputStream outputStream = urlConnection.getOutputStream();
// (...)

然后使用这个方面:

package de.scrum_master.aspect;

import java.net.HttpURLConnection;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class MyAspect {
  @Pointcut("call(* java.net.HttpURLConnection.connect()) && target(connection)")
  public void connectMethodCall(HttpURLConnection connection) {}

  @Around("connectMethodCall(connection)")
  public Object onGetUrlConnection(ProceedingJoinPoint pjp, HttpURLConnection connection) throws Throwable {
    connection.setRequestProperty("From", "user@example.com");
    return pjp.proceed();
  }
}

或者更紧凑一点,如果您不需要该点可重复使用,因为您只在一个建议中使用它:

@Aspect
public class MyAspect {
  @Around("call(* java.net.HttpURLConnection.connect()) && target(connection)")
  public Object onGetUrlConnection(ProceedingJoinPoint pjp, HttpURLConnection connection) throws Throwable {
    connection.setRequestProperty("From", "user@example.com");
    return pjp.proceed();
  }
}

控制台日志将是:

user@example.com
false : 405

关于java - 使用 AspectJ 更改对象属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53928815/

相关文章:

java - 在简单的数据库驱动的 Java Web 应用程序中使用异常

java - AOP中调用和执行的区别

exception - 如何在 AspectJ 中围绕建议重新抛出异常

java - 如何使用 Spring AOP 强制使用通用日志格式。想要附加一个字符串,例如每个记录器中的服务名称

java - 是否保证为 AspectJ 方面调用静态初始化程序?

java - 如何使用 Java/JavaFX 代码读取第二个数组上的 JSON 对象

java - 如何在反斜杠处拆分java字符串

java - 如何在 Android 应用程序中集成特殊字体 (.ttf)?

spring - 从 ProceedingJoinPoint 获取 java.lang.reflect.Method?

java - 如何访问 Java 方面中指定的参数?