powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / EJB 3.1: странное поведение @Singleton при использовании @WebListener?
5 сообщений из 5, страница 1 из 1
EJB 3.1: странное поведение @Singleton при использовании @WebListener?
    #38816213
Dim666
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Просьба не пинать. С 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
EJB 3.1: странное поведение @Singleton при использовании @WebListener?
    #38816233
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dim666p.s. Идею использовать вместе @Singleton и @WebListener взял из этого примера .

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

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

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



То можно узнать действительно ли создаются 2 экземпляра и увидеть кто именно их создаёт.
...
Рейтинг: 0 / 0
EJB 3.1: странное поведение @Singleton при использовании @WebListener?
    #38816371
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
@Singleton in java EJB
Be careful with Singleton Session Bean
Насколько я понимаю, аннотация @Singleton должна использоваться тогда, когда у вашего кода проблемы с многопоточностью, но если одного экземпляра не хватит для обслуживания запросов, контейнер создаст ещё один или даже несколько.
...
Рейтинг: 0 / 0
EJB 3.1: странное поведение @Singleton при использовании @WebListener?
    #38816460
Dim666
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
5 сообщений из 5, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / EJB 3.1: странное поведение @Singleton при использовании @WebListener?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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