代码之家  ›  专栏  ›  技术社区  ›  Oliver Drotbohm

如何查找引用方法的第一个声明方法

  •  2
  • Oliver Drotbohm  · 技术社区  · 16 年前

    假设您有一个通用接口和一个实现:

    public interface MyInterface<T> {
    
      void foo(T param);
    }
    
    public class MyImplementation<T> implements MyInterface<T> {
    
      void foo(T param) {
    
      }
    }
    

    这两种类型是我提供的框架类型。在下一步中,我希望允许用户扩展该接口并重新声明 foo(T param) 可能需要进一步的注释。

    public interface MyExtendedInterface extends MyInterface<Bar> {
    
      @Override
      void foo(Bar param);
    
      // Further declared methods
    }
    

    我为扩展接口创建了一个AOP代理,并拦截对进一步声明的方法的调用。AS foo(…) 现在重新申报 MyExtendedInterface 我不能简单地调用 MethodInvocation.proceed() 作为 MyImplementation 仅实现 MyInterface.foo(…) 而不是 MyExtendedInterface.foo(…) .

    那么,有没有一种方法可以访问最初声明方法的方法?关于这个例子,有没有一种方法可以发现 foo(Bar param) 被宣布为 MyInterface 最初,可以进入搭桥 Method 实例?

    我已经尝试按名称和参数类型扫描基类方法以匹配,但当泛型弹出和 MyImplementation.getMethod("foo", Bar.class) 显然是扔了一个 NoSuchMethodException . 我已经知道了 我的扩展接口 类型 My接口 Bar . 所以如果我能在 我的实施 我的数学算法实际上可以计算出来。

    其他信息:

    我为创建代理 我的扩展接口 如下:

    ProxyFactory factory = new ProxyFactory();
    factory.setTarget(new MyImplementation());
    factory.setInterfaces(new Class[] { MyExtendedInterface.class });
    factory.addInterceptor(new MyInterceptor(MyExtendedInterface.class));
    

    拦截器几乎扫描方法并对中声明的所有方法执行JPA查询。 我的扩展接口 但路由中声明的方法的所有方法调用 My接口 到代理目标。只要方法来自 My接口 不会重新声明为目标,然后不再实现它。

    public class MyInterceptor implements MethodInterceptor {
    
      public Object invoke(final MethodInvocation invocation)
                throws Throwable {
    
        // handling of query methods
        // else
    
        invocation.proceed();
        // ^^ works if not redeclared but not if
      }
    }
    

    所以我要做的不是调用,而是检测 最初声明被调用的 并在目标上手动调用它。

    2 回复  |  直到 16 年前
        1
  •  1
  •   Oliver Drotbohm    16 年前

    好的,这里是我提出的解决方案:正如我所知,基类和IT泛型结构(在本例中T的含义)以及 MyExtendedInterface 类型 MyInterface Bar 我可以扫描基本实现以查找可能的匹配项,如下所示(伪代码):

    for all methods {
    
       skip those with non matching name and parameters length;
    
       for all generic parametertypes {
    
         if typename = T then concrete type has to be Bar
         ...
       }
    }
    

    在这种情况下,我不需要一个通用的解决方案,所以这似乎是可行的。

        2
  •  0
  •   Bozho    16 年前

    整个情况似乎很奇怪。您不能应用在上声明的AOP MyExtendedInterface MyImplementation ,因为它不实现它。

    其次,我不理解为什么它关系到哪个接口定义了一个方法,因为它是调用该方法的实现。

    除此之外,还可以通过 getDeclaredMethods() . 然后您可以对它们进行迭代,并找到符合您的条件(名称)的内容。