我对如何在AOP中使用Fegn客户端很感兴趣。例如:
应用程序编程接口:
public interface LoanClient {
@RequestLine("GET /loans/{loanId}")
@MeteredRemoteCall("loans")
Loan getLoan(@Param("loanId") Long loanId);
}
配置:
@Aspect
@Component // Spring Component annotation
public class MetricAspect {
@Around(value = "@annotation(annotation)", argNames = "joinPoint, annotation")
public Object meterRemoteCall(ProceedingJoinPoint joinPoint,
MeteredRemoteCall annotation) throws Throwable {
// do something
}
}
但我不知道如何“拦截”api方法调用。我哪里出错了?
更新:
我的Spring课注解:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MeteredRemoteCall {
String serviceName();
}
您的情况有些复杂,因为您有几个问题:
贷款客户
不是Spring@Component
。call()
,而只支持执行 ()
。也就是说,它只编织到执行方法的地方,而不是调用它的地方。@MeteredRemoteCall
)上的注释永远不会被其实现类继承。事实上,方法注释在Java中永远不会继承,只有从类(不是接口!)到相应子类的类级注释。也就是说,即使你的注释类有一个@Inherited
元注释,它对@Target({元素类型.METHOD})
没有帮助,而只对@Target({元素类型.TYPE})有帮助
。更新:由于我之前已经多次回答了这个问题,所以我刚刚记录了这个问题,以及使用AspectJ模拟接口和方法的注释继承中的解决方法。那么你能做什么呢?最好的选择是在Spring应用程序中通过LTW(加载时编织)使用完整的AspectJ。这使您能够使用call()
切入点,而不是由Spring AOP隐式使用的execution()
。如果您在AspectJ中的方法上使用@annotation()
切入点,它将同时匹配调用和执行,正如我将在一个单独的示例中展示的那样(没有Spring,但效果与Spring中的LTW AspectJ相同):
标记批注:
package de.scrum_master.app;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MeteredRemoteCall {}
虚假客户端:
这个示例客户端获取完整的StackOverflow问题页面(HTML源代码)作为字符串。
package de.scrum_master.app;
import feign.Param;
import feign.RequestLine;
public interface StackOverflowClient {
@RequestLine("GET /questions/{questionId}")
@MeteredRemoteCall
String getQuestionPage(@Param("questionId") Long questionId);
}
驱动程序应用:
出于演示目的,此应用程序以三种不同的方式使用Flygn客户端界面:
package de.scrum_master.app;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import feign.Feign;
import feign.codec.StringDecoder;
public class Application {
public static void main(String[] args) {
StackOverflowClient soClient;
long questionId = 41856687L;
soClient = new StackOverflowClient() {
@Override
public String getQuestionPage(Long loanId) {
return "StackOverflowClient without Feign";
}
};
System.out.println(" " + soClient.getQuestionPage(questionId));
soClient = new StackOverflowClient() {
@Override
@MeteredRemoteCall
public String getQuestionPage(Long loanId) {
return "StackOverflowClient without Feign + extra annotation";
}
};
System.out.println(" " + soClient.getQuestionPage(questionId));
// Create StackOverflowClient via Feign
String baseUrl = "http://stackoverflow.com";
soClient = Feign
.builder()
.decoder(new StringDecoder())
.target(StackOverflowClient.class, baseUrl);
Matcher titleMatcher = Pattern
.compile("<title>([^<]+)</title>", Pattern.CASE_INSENSITIVE)
.matcher(soClient.getQuestionPage(questionId));
titleMatcher.find();
System.out.println(" " + titleMatcher.group(1));
}
}
没有方面的控制台日志:
StackOverflowClient without Feign
StackOverflowClient without Feign + extra annotation
java - How to use AOP with Feign calls - Stack Overflow
如您所见,在案例#3中,它只打印了这个StackOverflow问题的标题。;-)我使用正则表达式匹配器是为了从HTML代码中提取它,因为我不想打印整个web页面。
方面:
这基本上是您的方面,带有额外的连接点日志记录。
package de.scrum_master.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import de.scrum_master.app.MeteredRemoteCall;
@Aspect
public class MetricAspect {
@Around(value = "@annotation(annotation)", argNames = "joinPoint, annotation")
public Object meterRemoteCall(ProceedingJoinPoint joinPoint, MeteredRemoteCall annotation)
throws Throwable
{
System.out.println(joinPoint);
return joinPoint.proceed();
}
}
控制台日志和方面:
call(String de.scrum_master.app.StackOverflowClient.getQuestionPage(Long))
StackOverflowClient without Feign
call(String de.scrum_master.app.StackOverflowClient.getQuestionPage(Long))
execution(String de.scrum_master.app.Application.2.getQuestionPage(Long))
StackOverflowClient without Feign + extra annotation
call(String de.scrum_master.app.StackOverflowClient.getQuestionPage(Long))
java - How to use AOP with Feign calls - Stack Overflow
如您所见,以下连接点会为三种情况中的每一种拦截:
我希望这能帮助你理解发生了什么以及为什么。
底线:使用完整的AspectJ,以便让你的切入点与调用()
连接点匹配。然后你的问题就解决了。
价值万元具备小型呼叫中心能力,适用于电话销售、客户回访、渠道管理等场景。 外呼中心开通条件 【温馨提示】 外呼中心费用与钉钉智能电话保持一致。 外呼中心价值 开通外呼中心入口 外呼中心入口 外呼中心入口 简单三步完成呼叫任务 1.创建呼叫任务 创建呼叫任务,可从外部联系人批量导入,客户跟进更有计划性。 注: 外呼时间有限制,仅限早上7:00~20:00。 可以创建10个任务,单个任务导入上限200
假设我们有一段无聊的代码,我们都必须使用: 切换到Java 8后,我的IDE告诉我,我可以将此代码替换为对方付费呼叫,它会自动生成: 然而,这给了我一个错误: Steam中的collect(java.util.stream.Collector)不能应用于:(java.util.stream.Collector,capture,java.util.List) 我尝试转换参数,但它给了我未定义的和,I
但是上行和下行都不起作用 当我使用上行链路或下行链路时,我的应用程序行为不端,而当我使用其他来源时,我的应用程序工作正常
问题内容: 我需要从被叫方获取呼叫者信息(什么文件/什么行)。我了解到可以为此目的使用inpect模块,但不能完全使用它。 如何使用inspect获取那些信息?还是有其他方法来获取信息? 问题答案: 呼叫者的帧比当前帧高一帧。您可以用来查找呼叫者的框架。然后使用inspect.getframeinfo获取调用者的文件名和行号。
1、接口声明 业务流程图: 2、接口调用 2.1、校验账号 接口说明: 接口类型:主动调用接口 接口作用:校验登录账号是否与appid符合。 请求方式: GET 请求地址: https://icall.sobot.com/api/icall/5/task/check_login_name 请求参数: 参数 类型 必填 名称 备注 appid 字符串 是 智齿分配 signature 字符串 是 智
语境 我们正在Twilio中构建一个预约确认和连接应用程序,目前正在使用Studio。 它通过WhatsApp与用户通话,然后在他们准备好预约时通过正常的语音运营商服务拨打他们的电话,然后将他们的电话与呼叫中心代理连接。 null 非常感谢您的任何建议!