Jakarta ee 同一实例中的CDI调用侦听器注释方法

Jakarta ee 同一实例中的CDI调用侦听器注释方法,jakarta-ee,interceptor,cdi,Jakarta Ee,Interceptor,Cdi,这是我的DAO实现,我将加载整个表并在内存中缓存一段时间 @ApplicationScoped public class DataAccessFacade { @Inject private EntityManager em; @CacheOutput public Map<String, String> loadAllTranslation() { List<Translation> list = em.createQuery("

这是我的DAO实现,我将加载整个表并在内存中缓存一段时间

@ApplicationScoped
public class DataAccessFacade {

   @Inject
   private EntityManager em;

   @CacheOutput
   public Map<String, String> loadAllTranslation() {
      List<Translation> list = em.createQuery("select t from Translation t").getResultList();    
      Map<String, String> result = new HashMap<String, String>();
      // do more processing here, omitted for clarity     
      return result;
   }

   public String getTranslation(String key) {
      return loadAllTranslation().get(key);
   }

}
在客户机中,如果调用dataAccessFacade.loadAllTranslation(),我将看到已执行侦听器逻辑

如果我调用dataAccessFacade.getTranslation(),它在内部调用loadAllTranslation(),那么我没有看到拦截器被执行

这里有什么问题


如何解决

绑定到类的拦截器将拦截所有方法。看起来您已经选择将拦截器(@CacheOutput?)绑定到特定的方法,而不是在类级别

我想,如果除了loadAllTranslation之外,还显式地将拦截器绑定到getTranslation方法,那么您将看到拦截器在这两种情况下都工作


我没有在规范中找到任何解释来解释当前的行为。我的猜测是,它可以被认为是一种封装(信息隐藏)。在外部,没有理由期望对getTranslation的调用会导致对loadAllTranslation的调用。如果拦截器作为getTranslation调用的结果被调用(没有显式注释),那么它可能被视为泄漏了类的内部工作细节

这是CDI规范中的正确行为。只有“客户端”类调用的方法才被视为“业务方法”,因此会被拦截。

只需在DataAccessFacade中执行以下操作:

@Inject
private Provider<DataAccessFacade> self;

public String getTranslation(String key) {
  return self.get().loadAllTranslation().get(key);
}
@Inject
私人供应商自身;
公共字符串getTranslation(字符串键){
返回self.get().loadAllTranslation().get(键);
}

我尝试将注释移动到类级别,结果相同。不太确定。你能试试这个非常简单的业务拦截器,看看你得到了什么:如果我们不知道对象是如何注入的呢?它可能是一个子类,和/或在注入点处可能有限定符。有没有办法获得客户机看到的相同对象?
@Inject
private Provider<DataAccessFacade> self;

public String getTranslation(String key) {
  return self.get().loadAllTranslation().get(key);
}