java - Spring AOP 监控 Apache HttpClient.execute

标签 java spring aop spring-aop

我想监控传出请求的时间以跟踪我的应用程序中的 HTTP 集成。所有这些的公共(public)代码路径是 HttpClient.execute所以这似乎是 AOP 的自然目标:

@Around("execution(* org.apache.http.client.HttpClient.execute(..)) && args(httpUriRequest)")
public Object timeApacheRequest(ProceedingJoinPoint proceedingJoinPoint, HttpUriRequest httpUriRequest) throws Throwable {
    // etc.
}

但是,当我使用代理时,与 Spring HttpComponentsClientHttpRequestFactory 交互代码炸毁了它的instanceof检查传入的代理。

Caused by: java.lang.IllegalArgumentException: 'httpClient' is not of type CloseableHttpClient Object of class [com.sun.proxy.$Proxy22] must be an instance of class org.apache.http.impl.client.CloseableHttpClient

运算符(operator)检查HttpComponentsClientHttpRequestFactory :

public HttpComponentsClientHttpRequestFactory(HttpClient httpClient) {
    Assert.notNull(httpClient, "'httpClient' must not be null");
    Assert.isInstanceOf(CloseableHttpClient.class, httpClient, "'httpClient' is not of type CloseableHttpClient");
    this.httpClient = (CloseableHttpClient) httpClient;
}

是否有更好的方法来构建我的代理来避免这个问题?

澄清一下,目前我使用 @EnableAspectJAutoProxy 建立当前代理。声明 bean 的配置类上的注释。

最佳答案

默认情况下,@EnableAspectJAutoProxy(以及大多数生成代理的配置,@EnableTransactionManagementEnableAsync等)使用 JDK proxies

JDK代理仅支持 super 接口(interface)。 newProxyInstance 返回的实例(创建 JDK 代理的入口点)将具有 Proxy 的父类(super class)型。

为了支持您的方面和建议,Spring 必须代理与您的连接点匹配的任何实例。由于默认配置,这些代理仅维护真实对象的 super 接口(interface)。 CloseableHttpClient 是一个抽象类。那就丢了。代理没有该类型,因此 instanceof 将失败。

相反,您可以将 @EnableAspectJAutoProxy#proxyTargetClass() 配置为 true,以便 Spring 使用 CGLIB 来代理您的对象。 CGLIB 比 JDK 代理更强大。 CGLIB 可以子类化目标对象的类(除非其类是 final 或具有 private 构造函数)。

代理将成为 CloseableHttpClient 的子类型,并且 instanceof 可以工作。

关于java - Spring AOP 监控 Apache HttpClient.execute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33172485/

相关文章:

java - Spoj 上的代码提交出现运行时错误 (NZEC)

java - JSP 中的 HTTP 请求 (POST) 字段大小限制和 Request.BinaryRead

java - @Async 不适合我

java - 如何通过 Jackson Parser 从 Java 实例返回 String 对象

c# - 什么是控制反转/面向方面意义上的 .NET 代理对象?

java - 是否有一种聪明的方法来单元测试 AspectJ 策略执行方面?

java - 启用 Spring AOP 或 AspectJ

java - 如何将枚举类型设置为字符串类型

java - 嵌套基类出现莫名其妙的 Netbeans 可序列化警告

java - Spring - SpringJUnit4ClassRunner 仍然使用 LOG4J 1 而不是 2?