CDI 在同一实例中调用拦截器注释方法

发布于 2024-09-25 19:57:42 字数 1184 浏览 7 评论 0原文

这是我的 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(),我将看到拦截器逻辑已执行

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

这里有什么问题?

怎么解决呢?

here is my DAO implementation, i will load the whole table and cached in memory for a certain period of time

@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);
   }

}

here is my jersey client

@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); 
}

in the client if i call the dataAccessFacade.loadAllTranslation(), i will see the interceptor logic been executed

if i call the dataAccessFacade.getTranslation() which internally call the loadAllTranslation(), then i didn't see the interceptor been executed

what is the problem here?

how to solve it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

瑾夏年华 2024-10-02 19:57:44

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

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

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

An interceptor bound to a class will intercept all methods. It looks like you have chosen to bind your interceptor (@CacheOutput?) to specific methods rather than at the class level.

I imagine that if you explicitly bound your interceptor to the getTranslation method in addition to loadAllTranslation then you would see the interceptor working in both situations.

I have not found any explanation in the specification to explain the current behaviour. My guess is that it could be thought of as a kind of encapsulation (information hiding). Externally, there is no reason to expect that a call to getTranslation would result in a call to loadAllTranslation. If the interceptor was to be invoked as the result of a call to getTranslation (without an explicit annotation) it could be seen as leaking the details of the class' internal workings.

拒绝两难 2024-10-02 19:57:43

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

@Inject
private Provider<DataAccessFacade> self;

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

just do the following in your DataAccessFacade:

@Inject
private Provider<DataAccessFacade> self;

public String getTranslation(String key) {
  return self.get().loadAllTranslation().get(key);
}
◇流星雨 2024-10-02 19:57:42

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

This is the correct behavior as in the CDI spec. Only methods called by "client" classes are considered "business methods" and, thus, are intercepted.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文