Как тип области влияет на способ повторного использования объекта EntityQuery - PullRequest
3 голосов
/ 03 июля 2010
for (...) {
    UserList userList = (UserList) Component.getInstance(UserList.class, ScopeType.METHOD);
    userList.getUserByEmailAddress(emailId);
}

Существуют различные типы ScopeType, которые поддерживаются в Seam (например, МЕТОД, СТРАНИЦА, СОБЫТИЕ, ПРИЛОЖЕНИЕ). В настоящее время мы используем метод МЕТОД для получения объекта пользователя по идентификатору электронной почты. Приведенный выше код присутствует в цикле for (то есть для набора адресов электронной почты пользователя мы извлекаем объект пользователя). Это правильный ScopeType или было бы предпочтительнее переместить объявление UserList над циклом for

Мы наблюдали в некоторых типах областей действия, что объект userList используется повторно, может кто-то уточнить, как он действительно работает. Существуют ли какие-либо инструменты внутри шва, которые помогут вам понять, как эти объекты используются повторно (мы включили некоторую регистрацию трассировки, но было сделано слишком много вызовов, и это было не совсем понятно)

1 Ответ

1 голос
/ 12 августа 2010

ScopeType.METHOD сообщает

Каждый вызов сессионного компонента или компонента JavaBean помещает новый контекст метода в стек контекстов метода, связанных с текущим потоком .Контекст уничтожается, когда метод возвращается.

Большая часть функциональности Seam реализована в виде набора встроенных перехватчиков Seam.Здесь приведен фрагмент кода MethodContextInterceptor (встроенного перехватчика Seam), который API говорит

Устанавливает контекст METHOD и снимает с прокси SFSB на время вызова

MethodContextInterceptor.java См. Комментарии ниже и сравните их с выделенным текстом выше

@AroundInvoke
public Object aroundInvoke(InvocationContext ctx) throws Exception {
    Component comp = getComponent();

    String name = comp.getName();
    Object target = ctx.getTarget();
    Method method = ctx.getMethod();
    Object[] parameters = ctx.getParameters();

    /**
      * beginMethod
      *
      * Takes care of putting a NEW method context onto the stack of method contexts
      */
    Context outerMethodContext = Lifecycle.beginMethod();

    try {
        Contexts.getMethodContext().set(name, target);
        Contexts.getMethodContext().set("org.jboss.seam.this", target);
        Contexts.getMethodContext().set("org.jboss.seam.method", method);
        Contexts.getMethodContext().set("org.jboss.seam.parameters", parameters);
        Contexts.getMethodContext().set("org.jboss.seam.component", comp);

        /**
          * And after method return 
          */ 
        return ctx.proceed();
    } finally {
        /**
          * endMethod Takes care of destroying The previous added method context
          */       
        Lifecycle.endMethod(outerMethodContext);
    }
}

Как видите, я не вижу особого поведения, предоставляемого ScopeType.METHOD.Я думаю, что Гэвин Кинг, основатель проекта Seam, создал The ScopeType.METHOD в качестве дополнительной области, которую можно использовать сзади.Даже книга «Шов в действии» не охватывает область действия ScopeType.METHOD.

Поэтому каждый раз, когда вы вызываете getUserByEmailAddress , описанная выше процедура выполняется.Что касается контекста, книга «Шов в действии» ясна

Контекст определяет, где можно найти имя переменной и как долго она висит вокруг

Таким образом, желаемая сфера должна составить ваш бизнес.

О EntityQuery ???Вот что говорит книга «Шов в действии»

Если вы выполняете запрос каждый раз, когда вам нужно представить результаты, вы вводите отмену давление в базу данных ,С другой стороны, если вы слишком долго держитесь за результаты, вы в конечном итоге будете кормить пользователей устаревшей информацией , которая может их запутать или, что еще хуже, заставить их принимать неправильные решения.

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

  • Параметр ограничения запроса
  • Порядок сортировки
  • Максимальное значение результата
  • Первое смещение результата
  • Результаты очищаются вручную с помощью вызова функции refresh ()

Последний элемент полезен при обновлении некоторого @Entity и необходимости обновления сохраненного набора результатов.Вы можете сделать это с помощью события Seam.Но , если вы всегда хотите новый результирующий набор , установите свой EntityQuery как ScopeType.EVENT и используйте его вместо цикла for вместо

UserList userList = (UserList) Component.getInstance(UserList.class, ScopeType.EVENT);
for (...) {
    userList.getUserByEmailAddress(emailId);
}

Здесь идет параллельное сравнение между Seam иОбласть действия пружины

Seam                               Spring            Suited for
ScopeType.STATELESS                singleton         Service, repositories, Thread-safe components
ScopeType.APPLICATION              singleton         Service, repositories, Thread-safe components
ScopeType.SESSION                  session           User login
ScopeType.CONVERSATION             -                 Page flow
ScopeType.PAGE                     -                 Server-side based component model
ScopeType.EVENT                    request           Non Thread-safe components

Примечание. ScopeType.CONVERSATION не равно потоку Spring.Шов ScopeType.CONVERSATION выходит за рамки веб-слоя.Даже контекст постоянства может быть включен в контекст разговора.Имейте в виду, что ScopeType.PAGE имеет смысл, когда у вас есть серверная структура компонентов, такая как JSF, Wicket и т. Д. Обычно ScopeType.STATELESS используется, когда у вас полностью Java EE-окружение и ScopeType.APPLICATION, когдавы используете простые POJO вместо EJB.

...