Безстоящее и государственное предприятие Java Beans

Я просматриваю учебное пособие по Java EE 6, и я пытаюсь понять разницу между сеансом без состояния и состояниями beans. Если сеанс без состояния beans не сохраняет свое состояние между вызовами методов, почему моя программа действует так, как она есть?

package mybeans;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;

@LocalBean
@Stateless
public class MyBean {

    private int number = 0;

    public int getNumber() {
        return number;
    }

    public void increment() {
        this.number++;
    }
}

Клиент

import java.io.IOException;
import javax.ejb.EJB;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;
import mybeans.MyBean;
import java.io.PrintWriter;

@WebServlet(name = "ServletClient", urlPatterns = { "/ServletClient" })
public class ServletClient extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @EJB
    MyBean mybean;

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        PrintWriter out = response.getWriter();
        mybean.increment();
        out.println(mybean.getNumber());
    }

}

Я ожидал, что getNumber будет возвращать 0 каждый раз, но он возвращает 1, и перезагрузка сервлета в моем браузере увеличивает его больше. Проблема заключается в том, что я понимаю, как работает безстоящий сеанс beans, а не с библиотеками или серверами приложений, конечно. Может ли кто-нибудь дать мне простой пример приветствия мирового типа сеанса без состояния bean, который ведет себя по-другому, когда вы меняете его на состояние?

Ответ 1

Важное отличие - это не частные переменные-члены, а связывание состояния с определенным пользователем (думаю, "корзина покупок" ).

Простой сеанс stateful session bean похож на сеанс в сервлетах. Сессионная сессия beans позволяет вашему приложению иметь этот сеанс, даже если нет веб-клиента. Когда сервер приложений извлекает сеанс без учета состояния bean из пула объектов, он знает, что он может использоваться для удовлетворения ЛЮБОГО запроса, поскольку он не связан с конкретным пользователем.

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

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

Ответ 2

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

В отличие от этого, сеанс состязания Beans (SFSB) выделенный для одного клиента на всю жизнь, нет обмена или объединения экземпляров (он может быть выведен из памяти после пассивации для сохранения ресурсы, но эта другая история) и поддерживать диалоговое состояние. Это означает, что переменные экземпляра bean могут хранить данные относительно клиента между вызовами метода. И это позволяет иметь взаимозависимые вызовы методов (изменения, сделанные одним методом, влияют на последующие вызовы методов). Многоступенчатые процессы (процесс регистрации, корзина покупок, процесс бронирования...) являются типичными вариантами использования для SFSB.

Еще одна вещь. Если вы используете SFSB, то вы должны избегать их вложения в классы с многопоточным характером, такие как сервлеты и управляемые JSF Beans (вы не хотите, чтобы они были доступны всем клиентам), Если вы хотите использовать SFSB в своем веб-приложении, вам необходимо выполнить поиск JNDI и сохранить возвращенный экземпляр EJB в объекте HttpSession для будущей активности. Что-то вроде этого:

try {
    InitialContext ctx = new InitialContext();
    myStateful = (MyStateful)ctx.lookup("java:comp/env/MyStatefulBean");
    session.setAttribute("my_stateful", myStateful);
} catch (Exception e) {
    // exception handling
}

Ответ 3

Без учета состояния и состояния в этом контексте не означает, что вы можете ожидать.

Стойкость с EJB относится к тому, что я называю диалоговым состоянием. Классическим примером является бронирование авиабилетов. Если он состоит из трех шагов:

  • Запасное сиденье
  • Плата за кредитную карту
  • Выдача билетов

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

Безстоящий сеанс beans не имеет такой возможности для диалогового состояния.

Глобальные переменные внутри сеанса bean (stateeless или stateful) - это нечто иное. Сессионная сессия beans будет иметь пул beans, созданный (поскольку bean может использоваться только в одном разговоре за раз), в то время как без состояния sesion beans часто будет только один экземпляр, который сделает глобальную переменную работает, но я не думаю, что это обязательно гарантировано.

Ответ 4

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

Ответ 5

Основные различия между двумя основными типами сеанса beans заключаются в следующем:

Без гражданства Beans

  • Сессия без состояния beans - это те, которые не имеют диалогового состояния с клиентом, который вызвал его методы. По этой причине они могут создавать пул объектов, которые могут использоваться для взаимодействия с несколькими клиентами.
  • Производительность wise stateless beans лучше, так как у них нет состояний для каждого клиента.
  • Они могут обрабатывать несколько запросов от нескольких клиентов параллельно.

Состояние > Beans

  • Сессионная сессия beans может поддерживать диалоговое состояние с несколькими клиентами одновременно и задача не распределяется между клиентами.
  • После завершения сеанса состояние не сохраняется.
  • Контейнер может сериализовать и сохранять состояние в качестве устаревшего состояния для будущего использования. Это делается для экономии ресурсов сервера приложений и поддержки отказов bean.

Ответ 6

У него хорошие ответы. Я хотел бы добавить небольшой ответ. Безстоящий Bean не должен использоваться для хранения данных клиента. Он должен использоваться для "моделирования действий или процессов, которые можно сделать одним выстрелом".