Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / EJB 3.1: странное поведение @Singleton при использовании @WebListener? / 5 сообщений из 5, страница 1 из 1
25.11.2014, 15:29
    #38816213
Dim666
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
EJB 3.1: странное поведение @Singleton при использовании @WebListener?
Просьба не пинать. С EJB 3.1 только начал знакомиться.

Есть вот такой Singleton-бин, смысл которого как-бы отслеживать http-сессии:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
@Singleton
@LocalBean
@WebListener
public class SessionBean implements HttpSessionListener {

    private static final Logger log = Logger.getLogger(SessionBean.class.getSimpleName());
    private static final HashMap<SessionBean, Integer> map = new HashMap<>();
    private static int number = 0;
    private int counter = 0;

    @PostConstruct
    public void appStartup() {
        Integer num = (++number);
        boolean newInstance = (map.put(this, num) == null);
        log.log(Level.INFO, "SessionBean({0}){1}", new Object[]{num, (newInstance ? " new!" : "")});
    }

    @PreDestroy
    public void appShutdown() {
        log.log(Level.INFO, "~SessionBean({0})", map.get(this));
    }

    public int getNum() {
        return map.get(this);
    }

    public int getCounter() {
        return counter;
    }

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        log.log(Level.INFO, "sessionCreated({0}) {1}", new Object[]{map.get(this), se.getSession().getId()});
        counter++;
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        log.log(Level.INFO, "sessionDestroyed({0}) {1}", new Object[]{map.get(this), se.getSession().getId()});
        counter--;
    }
}



И вот такой простейший сервлет:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
@WebServlet(name = "Servlet1", urlPatterns = {"/Servlet1"})
public class Servlet1 extends HttpServlet {

    @EJB
    private SessionBean sessionBean;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.getSession(true);
        try (PrintWriter out = response.getWriter()) {
            out.println("Bean(" + sessionBean.getNum() + ") has count: " + sessionBean.getCounter());
        }
    }
}



При деплое (в glassfish 4.1) в выводе вижу такое:
Код: powershell
1.
2.
3.
Info:   SessionBean(1) new!
Info:   Loading application [TestApp] at [/TestApp]
Info:   TestApp was successfully deployed in 515 milliseconds.


После 1-го обращения к сервлету через браузер (который выдаёт "Bean(2) has count: 0") появляется:
Код: powershell
1.
2.
Info:   sessionCreated(1) 6caaa2217dc45da80f2520fc651f
Info:   SessionBean(2) new!


После выгрузки приложения:
Код: powershell
1.
2.
3.
Info:   sessionDestroyed(1) 6caaa2217dc45da80f2520fc651f
Info:   ~SessionBean(1)
Info:   ~SessionBean(2)



Получается, что контейнер создаёт два экземпляра бина, помеченного как @Singleton. Разве это не противоречит его идеологии?

p.s. Идею использовать вместе @Singleton и @WebListener взял из этого примера .
p.p.s. Архив с maven-проектом в аттаче.
...
Рейтинг: 0 / 0
25.11.2014, 15:39
    #38816233
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
EJB 3.1: странное поведение @Singleton при использовании @WebListener?
Dim666p.s. Идею использовать вместе @Singleton и @WebListener взял из этого примера .

Идея выглядит очень сомнительной. Парочке NetBeans/GF я бы не доверял.
...
Рейтинг: 0 / 0
25.11.2014, 15:58
    #38816272
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
EJB 3.1: странное поведение @Singleton при использовании @WebListener?
Dim666,

Если в класс добавить конструктор

Код: java
1.
2.
3.
4.
 
public SessionBean(){
    Thread.dumpStack();
}



То можно узнать действительно ли создаются 2 экземпляра и увидеть кто именно их создаёт.
...
Рейтинг: 0 / 0
25.11.2014, 16:47
    #38816371
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
EJB 3.1: странное поведение @Singleton при использовании @WebListener?
@Singleton in java EJB
Be careful with Singleton Session Bean
Насколько я понимаю, аннотация @Singleton должна использоваться тогда, когда у вашего кода проблемы с многопоточностью, но если одного экземпляра не хватит для обслуживания запросов, контейнер создаст ещё один или даже несколько.
...
Рейтинг: 0 / 0
25.11.2014, 17:34
    #38816460
Dim666
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
EJB 3.1: странное поведение @Singleton при использовании @WebListener?
BlazkowiczDim666,

Если в класс добавить конструктор

То можно узнать действительно ли создаются 2 экземпляра и увидеть кто именно их создаёт.Конструктор вообще 3 раза отработал :-) Но для 1-го не выполнялись методы, помеченные @PostConstruct и @PreDestroy.

Как я понимаю, 1-й экземпляр создаёт org.glassfish.ejb.startup.EjbApplication.loadContainers, 2-й - com.sun.enterprise.web.WebApplication.start, 3-й - com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke (если кому интересно, то архив дапмов в аттаче).

В принципе наверно всё правильно: @Singleton должен обеспечивать единственный экземпляр бина для обращений от всех клиентов (в моём случае это обращение из сервлета)...
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / EJB 3.1: странное поведение @Singleton при использовании @WebListener? / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]