我想使用AOP修改接口方法的调用,并通过SPI通过反射调用另一种实现。
有什么办法可以通过某种方式将Pointcut / Around重定向到调用?
这是我的代码库
@Around(value = "@annotation(spiExtension)")
def aroundSourceMethod(joinPoint: ProceedingJoinPoint, spiExtension: SpiExtension): Unit = {
val interfaces = joinPoint.getTarget.getClass.getInterfaces
for(interface <- interfaces){
if (implementationLoadedByClazz.get(interface) == null) {
for (clazz <- ServiceLoader.load(interface)) {
val extensionClass: SpiExtensions = ComponentUtil.getComponentByImplementation(clazz.getClass, interface)
implementationsByCondition.put(extensionClass.condition, extensionClass)
implementationLoadedByClazz.put(interface, extensionClass)
}
}
}
invokeSpecificImplementation(joinPoint)
}
private def invokeSpecificImplementation(joinPoint: ProceedingJoinPoint) = {
val methodSignature = joinPoint.getSignature.asInstanceOf[MethodSignature]
val method = methodSignature.getMethod
val args = joinPoint.getArgs
val condition = args.apply(0).asInstanceOf[String]
val instance:Object = implementationsByCondition(condition)
Proxy.getInvocationHandler(instance).invoke(instance, method, args)
}
如您所见,我使用反射调用所需的方法,但是对方法的原始请求会发生什么。
我们通常会在@Around方法中添加joinPoint.proceed();
答案 0 :(得分:1)
无限循环是因为AOP将以与原始相同的方式处理您的呼叫。您需要一种方法(一个标志)来捕获此类用例,并跳过第二个调用的操作。并检查您是否具有动态代理,然后可以获取原始功能并直接调用它。