CDI拦截器:如何拦截`this`调用或获取当前代理对象?

时间:2016-12-07 13:59:28

标签: java java-ee cdi

我有一个用户将继承的类并实现两个方法:navigateForwards()navigateBackwards()(它是一个类似向导的Web应用程序)。 用户可能希望在这些方法中添加拦截器。

另一个类(假设它是框架的一部分)将找到相应的子类select()并调用navigate(String)方法,该方法将调用navigateForwards()navigateBackwards() 。此时拦截器将不再起作用,因为它是一个未经过代理的方法调用。我可以在navigate()方法中添加拦截器,但这不是子类对覆盖感兴趣的方法。

是否有一种简单的方法告诉CDI拦截一种否则不会被截获的方法?

我提出了几种解决这个问题的一般方法,但它们似乎都不是很有希望:

  1. 以某种方式获取调用我的代理对象。这需要某种自我注入来复制“框架”类中的select()调用。

  2. 从CDI获取方法的拦截器列表并手动调用它们。不知。

  3. 使用DeltaSpike的EnableInterceptorsProxyFactory http://deltaspike.apache.org/documentation/proxy.html来包装this。这可能很慢和/或发现其他限制。

  4. CDI扩展可能还有其他选项,但我不确定扩展能够做什么。

    我已经尝试过将所有内容颠倒过来并使用装饰器而不是基类,希望对委托对象的调用会被截获,但事实并非如此,至少在JBoss EAP 6.x中没有(最有可能是6.4,但是当我测试时它可能是早期的版本。)

1 个答案:

答案 0 :(得分:0)

我找到的最简单的解决方案(由于某些晦涩的原因以前没有发生过),正在使navigate()静态并明确传递对象(例如self)。

从外面看,类有点奇怪,因为看起来它可能有一个常规的非静态方法,但有一个静态方法。 OTOH它完成了工作并且易于理解。我需要当前的代理对象,所以我将它传入。它是微不足道的,它保持了拦截器的行为。

我的项目中只需要更改一些调用,但其他项目会有不同的需求,因此不幸的是它不是一般的解决方案。这就是为什么我不接受我自己的答案。