有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

具有以下层次结构:

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",
                       methodName, Arrays.asList(args), 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,而不是既打印AccessorSub01也打印AccessorSub02

如果可能-如何实现这一目标?,根据具体情况,我需要AccessorSub01AccessorSub02

当然

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

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

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


共 (1) 个答案

  1. # 1 楼答案

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

    你的问题也是XY problem的一个例子(就像我刚才评论的前一个问题一样),也就是说,你描述了你想象如何从技术上解决一个问题,而不是说你实际上想要实现什么。目前,我只能推测您提出问题的方式,我猜您的应用程序设计在某些方面存在缺陷。例如,为了满足缓存需求,或者使用工厂而不是直接使用new Something(),您可能更愿意拦截构造函数调用而不是方法调用,但这是推测,就像我说的。你没有分享足够的信息让我提出更具体的解决方案