CDI 在同一实例中调用拦截器注释方法
这是我的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
绑定到类的拦截器将拦截所有方法。看起来您已经选择将拦截器(@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.
只需在 DataAccessFacade 中执行以下操作:
just do the following in your DataAccessFacade:
这是 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.