Аннотированный метод перехватчика вызова 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.getTranslation(), который внутренне вызывает loadAllTranslation(), то я не вижу, чтобы перехватчик был выполнен

в чем проблема?

как это решить?


person Dapeng    schedule 01.10.2010    source источник


Ответы (3)


Это правильное поведение, как в спецификации CDI. Только методы, вызываемые «клиентскими» классами, считаются «бизнес-методами» и, таким образом, перехватываются.

person Hendy Irawan    schedule 16.09.2011

просто сделайте следующее в вашем DataAccessFacade:

@Inject
private Provider<DataAccessFacade> self;

public String getTranslation(String key) {
  return self.get().loadAllTranslation().get(key);
}
person Xavier Dury    schedule 19.06.2014
comment
Что, если мы не знаем, как был введен объект? Это может быть подкласс и/или он может иметь квалификаторы в точке внедрения. Есть ли способ получить тот же объект, который видит клиент? - person marcus; 13.09.2016

Перехватчик, привязанный к классу, будет перехватывать все методы. Похоже, вы решили связать свой перехватчик (@CacheOutput?) с конкретными методами, а не на уровне класса.

Я предполагаю, что если бы вы явно привязали свой перехватчик к методу getTranslation в дополнение к loadAllTranslation, вы бы увидели, что перехватчик работает в обеих ситуациях.

Я не нашел в спецификации никаких объяснений текущего поведения. Я предполагаю, что это можно рассматривать как своего рода инкапсуляцию (сокрытие информации). Внешне нет оснований ожидать, что вызов getTranslation приведет к вызову loadAllTranslation. Если бы перехватчик вызывался в результате вызова getTranslation (без явной аннотации), это могло бы рассматриваться как утечка деталей внутренней работы класса.

person Mark McLaren    schedule 05.10.2010
comment
я попытался переместить аннотацию на уровень класса, тот же результат. - person Dapeng; 06.10.2010
comment
Не уверен. Не могли бы вы попробовать этот очень простой бизнес-перехватчик и посмотреть, что вы получите: easybeans.org/doc/userguide/en/chunk-integrated/ch04s04.html - person Mark McLaren; 06.10.2010