CDI call interceptor annotated method within same instance
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 ex开发者_Python百科ecuted
what is the problem here?
how to solve it?
This is the correct behavior as in the CDI spec. Only methods called by "client" classes are considered "business methods" and, thus, are intercepted.
just do the following in your DataAccessFacade:
@Inject
private Provider<DataAccessFacade> self;
public String getTranslation(String key) {
return self.get().loadAllTranslation().get(key);
}
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.
精彩评论