3

这是我的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);
   }

}

这是我的球衣客户

@Inject
DataAccessFacade dataAccessFacade;

@Path("/5")
@GET
@Produces(MediaType.TEXT_PLAIN)
public String t5(@QueryParam("id") String key) {
  // load the data from dataAccessFacade
  String text = dataAccessFacade.getTranslation(key); 
  String text2 = dataAccessFacade.loadAllTranslation().get(key); 
}

在客户端,如果我调用 dataAccessFacade.loadAllTranslation(),我将看到拦截器逻辑已执行

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

这里有什么问题?

如何解决?

4

3 回答 3

2

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

于 2011-09-16T09:55:00.263 回答
1

just do the following in your DataAccessFacade:

@Inject
private Provider<DataAccessFacade> self;

public String getTranslation(String key) {
  return self.get().loadAllTranslation().get(key);
}
于 2014-06-19T06:49:54.890 回答
-1

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

我想,如果除了 loadAllTranslation 之外,您还明确地将拦截器绑定到 getTranslation 方法,那么您会看到拦截器在这两种情况下都有效。

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

于 2010-10-05T22:09:54.990 回答