如何在@Around通知中调用proce方法之前检索方法声明的返回类型运行时类型

问题描述

具有以下层次结构:

Accessor
  AccessorSub01
  AccessorSub02

像一组简单的域类一样考虑它们

对于@Around咨询,我需要知道返回类型 运行时类型,但是 在致电之前 proceed()方法

通过此链接

我写了以下内容

@Around("Accessorpointcut.methodLevel05(methodLevel)")
public Object aroundMethodLevel05(ProceedingJoinPoint pjp,MethodLevel methodLevel) {
    String methodName = pjp.getSignature().getName();
    Object[] args = pjp.getArgs();
    System.out.printf("[AccessorAspect - aroundMethodLevel05] " +
                      "MethodName: %s - Arguments: %s - @MethodLevel: %s %n",methodName,Arrays.asList(args),methodLevel.value());

    Signature signature =  pjp.getSignature();
    Class<?> returnType = ((MethodSignature) signature).getReturnType();
    System.out.printf("[AccessorAspect - aroundMethodLevel05] Class<?> [ReturnType CanonicalName]: %s%n",returnType.getCanonicalName());

    //Todo: implement a cache control

    Object object = null;
    try {
        object = pjp.proceed();
    }
    catch (Throwable e) {
        System.err.printf("%s%n",e.getMessage());
    }

    System.out.printf("[AccessorAspect - aroundMethodLevel05] " +
                      "MethodName: %s - Arguments: %s - @MethodLevel: %s - Returns: %s %n",methodLevel.value(),object);
    return object;
}

考虑此界面:

public interface AccessorService {

    Accessor something01();
    Accessor something02();

}

如果使用以下命令,则@Around咨询代码可以正常工作:

@Override
@MethodLevel("something01")
public AccessorSub01 something01() {
    return new AccessorSub01("Something 01");
}

@Override
@MethodLevel("something02")
public AccessorSub02 something02() {
    return new AccessorSub02("Something 02");
}

方法声明中的返回类型和返回类型是相同的子类。对于前者,多态性是可能的。因此,根据情况,在@Around中会打印AccessorSub01AccessorSub02的建议

但是具有以下条件:

@Override
@MethodLevel("something01")
public Accessor something01() {
    return new AccessorSub01("Something 01");
}

@Override
@MethodLevel("something02")
public Accessor something02() {
    return new AccessorSub02("Something 02");
}

方法声明中的返回类型是超类,与接口声明相同,但是返回类型是子类。 @Around建议始终打印Accessor,而不打印AccessorSub01AccessorSub02

如果可能-如何实现此目标?我需要根据情况选择AccessorSub01AccessorSub02

当然

    Signature signature =  pjp.getSignature();
    Class<?> returnType = ((MethodSignature) signature).getReturnType();

适用于类/声明而不适用于运行时

记住:在调用proceed()方法之前,我需要此数据-因此在那个时间点还没有 object 。此请求需要它来实现一种缓存控制。

解决方法

您的问题意味着AspectJ或您将需要一个神奇的水晶地球仪,用以预测未来或一台时间机器。您怎么可能事先知道一个对象的类型,而该对象只会在以后尚未被调用的方法中创建?这甚至不是一个AspectJ问题,这本身就是一个逻辑问题。

您的问题也是XY problem的一个示例(就像您刚才提到的上一个问题一样),即您描述如何技术上解决问题,而不是说目标。我只能推测您当前提出问题的方式,我的猜测是您的应用程序设计存在某种缺陷。例如,也许您宁愿拦截构造函数调用而不是方法调用,以便满足您的缓存需求或直接使用工厂而不是new Something(),但这是猜测,就像我说的那样。您没有为我提供足够的信息来提出更具体的解决方案。