Как создать провайдеров Guice для объектов данных? - PullRequest
1 голос
/ 12 июня 2011

У меня вопрос: как я могу использовать мощь провайдеров хитрости (их способность охватывать экземпляры) для объектов данных?

Вот логическое обоснование: у меня есть класс в области сеанса WebPage, которыйизвлекает данные по веб-запросу из объекта базы данных DAO.

//Scope of WebPage: SESSION
class WebPage{
  Provider<DAO> daoProvider; //Scope of DAO: REQUEST

  WebPage(Provider<DAO> daoProvider){
     this.daoProvider = daoProvider;
  }

  public String getMyString(){
    return daoProvider.get().getMyString();
  }

  public int getMyInt(){
    return daoProvider.get().getMyInt();
  }
}

. Объект WebPage является частью веб-инфраструктуры, которая поддерживает все объекты страницы в сеансе.При каждом запросе getMyString и getMyInt методы вызываются несколько раз для извлечения значений перед их отображением пользователю на странице.Предположим, что объект DAO присоединен к одной конкретной строке таблицы и просто извлекает данные из этой строки.

По соображениям производительности мне нужно, чтобы daoProvider всегда возвращал один и тот же экземпляр, чтобы избежать переподключения кбаза данных каждый раз, когда getMyString или getMyInt вызывается.С другой стороны, экземпляр должен обновляться по запросам, чтобы любые обновления базы данных были видны пользователям после обновления страницы.

Итак, я ищу поставщика в области запросов DAOвнутри объекта WebPage в рамках сеанса.Проблема в том, что я не понимаю, как подключить его в Guice.Я пробовал это, но безрезультатно:

class DAO{
  Result row;

  DAO(int rowId){
    //opens DB connection and establishes a link
    //to the object in question
    this.row = attachRow(rowId);
  }

  String getMyString(){
    this.row.getData("mystring");
  }

  int getMyInt(){
    this.row.getIntData("myint");
  }
}

interface DAOProviderFactory {
  Provider<DAO> create(int rowId);
}

class DAOProviderFactoryImpl implements DAOProviderFactory {
  @Override
  public Provider<DAO> create(int rowId) {
    return new DAOProviderImpl(rowId);
  }
}

@RequestScoped
class DAOProviderImpl implements Provider<DAO> {
  int rowId;

  public DAOProviderImpl(int rowId) {
    this.rowId = rowId;
  }

  @Override
  public DAO get() {
    //I want this instance to be request-scoped!
    return new DAO(rowId);
  }
}

//Then bind it in the module
bind(DAOProviderFactory.class).to(DAOProviderFactoryImpl.class);

Это не сработало, так как вызов daoProvider.get() будет возвращать новый экземпляр (без границ) при каждом вызове.Я предполагаю, что причина этого в том, что мой объект DAOProviderImpl фактически не управляется Guice.Другая проблема - изрядное количество котельной.

Как я могу обслуживать экземпляр DAO с конкретным rowId, используя провайдера в области запроса?

Если кто-то может поставитьЯ на правильном пути, я был бы признателен!Заранее спасибо.

1 Ответ

2 голосов
/ 12 июня 2011

Здесь есть пара проблем. Во-первых, у вас есть эти DAOProviderFactory и DAOProviderFactoryImpl, которые требуют rowId для создания DAOProviderImpl, но вы никогда не используете их. Я также не уверен, как Guice вообще это запускает, так как в конструкторе DAO нет @Inject, а у вас нет действительного пользовательского DAO провайдера, связанного здесь.

В любом случае, я думаю, вы можете сделать что-то попроще здесь. Просто сделайте DAOFactory вот так:

@RequestScoped
public class DAOFactory {
  private final Map<Integer, DAO> daos = new HashMap<Integer, DAO>();

  public DAO getDao(int rowId) {
    DAO dao = daos.get(rowId);
    if (dao == null) {
      dao = new DAO(rowId);
      daos.put(rowId, dao);
    }
    return dao;
  }
}

Конечно, можно реализовать некоторый интерфейс, если хотите. Если по какой-то причине вы не знаете rowId в каждом месте, где вы извлекаете DAO, вы можете вместо этого сделать что-то, где вам сначала нужно инициализировать фабрику, установив ее rowId, а затем просто вернуть ее. DAO, который был создан в другом месте.

В любом случае, вы бы ввели Provider<DAOFactory> (объем запроса) в ваш WebPage или куда-либо еще.

Все это говорит, я не могу помочь, но думаю, что может быть лучший дизайн для вас, но не зная больше, я не уверен, что это будет.

...