Как написать аннотацию EJB 3.1

 
0
 
Java
ava
Atum | 18.02.2013, 12:28
Добрый день !

Вопрос такой : хочется создать свою аннотацию  для Stateful  Бина - чтобы можно было его инжектировать по средствам ее в Сервлете !

Хочется  написать такую аннотакцию которая бы позволяла добиться такого же эффекта как
и для Stateless бинов при их инжектировании в сервлет по средствам @EJB аннотации 

Называется к примеру @EJBStateful

Вопрос : Как еще реализовать?

servlet 3  + Stateful EJB 3.1

что есть :

1.Stateful Бин с бизнеес логикой , который хочется привязать к сессии пользователя.
2.Сервлет в котором этот бин получается из атрибута сессии !
3.ServletContextListener, HttpSessionListener  которые  и добавляют в сессию пользователя  этот бин как атрибут

сейчас поиск происходит через InitialContext().

Хочется реализовать это все так чтобы я просто в сервлете мог написать


@EJBStateful
private  FacadeStatefulBean  facadeStatefulBean;  


и работать с таким бином по привычной схеме. Возможно ли создать такую аннотацию? 



Реализация того как это работает сейчас :

@Stateful
@LocalBean
public class FacadeStatefulBean   {

private long id;

    public String info() {
        return "FacadeStatefulBean";
    }
    
    @Remove
    public void myRemove() {
        System.out.printf("---------FacadeStatefulBean myRemove id -----------", id);
    }

    @PostConstruct
    public void init() {
        id = System.currentTimeMillis();
        System.out.printf("---------FacadeStatefulBean  id = {%d} -----------", id);

    }

    @PreDestroy
    public void destroy() {
        System.out.printf("--------- FacadeStatefulBean destroy id = {0} -----------", id);
    }

    @PostActivate
    public void activate() {
        System.out.printf("--------- FacadeStatefulBean activate id = {%d} -----------", id);
    }

    @PrePassivate
    public void passivate() {
        System.out.printf("---------FacadeStatefulBean passivate id = {%d} -----------", id);
    }


}



сервлет который обслуживает запросы клиента


@WebServlet(name = "s1", urlPatterns = {"/s1"})
public class s4 extends HttpServlet {

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            HttpSession session = request.getSession(true);
           FacadeStatefulBean   facadeStatefulBean= (FacadeStatefulBean) session.getAttribute("FacadeStatefulBean");
             if(facadeStatefulBean!=null){
                   facadeStatefulBean.info(); 
            }
...

    }

}


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


@WebListener()
public class ServletListener implements ServletContextListener, HttpSessionListener {


    @Override
    public void sessionCreated(HttpSessionEvent se) {
        FacadeStatefulBean   facadeStatefulBean   = null;
        HttpSession session =   se.getSession();
        session.setMaxInactiveInterval(5); // как пример чтобы не создавать ресурсы на долго.
        try {
            Context context = new InitialContext();
             Object  o =   context.lookup("java:global/EAR/EJBModule/FacadeStatefulBeanl!ru.model.FacadeStatefulBean");
            FacadeStatefulBean= (FacadeStatefulBean) o; 
             
        } catch (NamingException ex) {
            Logger.getLogger(ServletListener.class.getName()).log(Level.SEVERE, null, ex);
        }
         
         
         
        
        session.setAttribute(FacadeStatefulBean", facadeStatefulBean);
        System.out.println("----ServletListener sessionCreated---  " );

    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
       HttpSession session =  se.getSession();
       FacadeStatefulBean ful = (FacadeStatefulBean) session.getAttribute("FacadeStatefulBean");
       ful.myRemove();
        System.out.println("----ServletListener sessionDestroyed---  " );

    }

Ответы (11)
ava
korian | 18.02.2013, 19:10 #
Цитата (Atum @  18.2.2013,  10:28 findReferencedText)
Хочется  написать такую аннотакцию которая бы позволяла добиться такого же эффекта как 
  и для Stateless бинов при их инжектировании в сервлет по средствам @EJB аннотации 


Я возможно чего-то не понимаю, но Stateless от Stateful ничем не отличается в данном случае. Т.е. если у вас работает инъекты со Stateless, то должны работать и со Stateful.
ava
Atum | 19.02.2013, 08:34 #
Хм, т.е. вы предлагаете в servlete  просто написать

@EJB
private  FacadeStatefulBean  facadeStatefulBean;
  

для Stateful  бина?

сомневаюсь что это пройдет .
ava
korian | 19.02.2013, 17:24 #
Цитата (Atum @  19.2.2013,  07:34 findReferencedText)
Хм, т.е. вы предлагаете в servlete  просто написать 

Вы так спрашиваете, что я аж сомневаться начал...
Верю, что да. Можете проверить?
ava
Atum | 20.02.2013, 10:03 #
Цитата (korian @ 19.2.2013,  17:24)
Цитата (Atum @  19.2.2013,  07:34 \\"findReferencedText\\")
Хм, т.е. вы предлагаете в servlete  просто написать 


Вы так спрашиваете, что я аж сомневаться начал...

Верю, что да. Можете проверить?

Насколько я понимаю текущую схему работы Сервлета и EJB.

экземпляр сервлета всегда один но сервлет многопоточный - и когда мы в нем инжектируем Stateless  бин  - мы фактически создаем ссылку на EJB-контейнер который нам выдает экземпляры Stateless бинов .
Для каждого пользователя -потока  будет создаваться свой бин или браться из Пула EJB контейнера.

Для Stateful  такая схема не подходит - потому что Stateful бин хранит состояние .  
Простой пример - два одновременных запроса от двух пользователей оба хотят поменять значение переменной в Stateful  бине - дергают  функцию setName(name);

какой будет результат и механизм вызова Stateful бина в Сервлете ?
ava
korian | 20.02.2013, 14:31 #
В месте инъекции хранится не сам объект, а прокси-объект. Он то и разгуливает, для какого объекта вызвать setName.
ava
Atum | 21.02.2013, 10:41 #
Цитата (korian @ 20.2.2013,  14:31)
В месте инъекции хранится не сам объект, а прокси-объект. Он то и разгуливает, для какого объекта вызвать setName.

Пример!

создайте два бина Stateless  и Stateful  .
Поставьте в них счетчик int count =0;
и увеличивайте его при вызове функции info()

public int info(){
return ++count;
}

два сервлета s1Stateless  и s1Stateful    с @EJB этих бинов.

для Stateless  - должен быть уникальный счетчик для каждого пользователя на его сессию.

для s1Stateful    - будет каша в выводе -  если будет несколько клиентов и несколько браузеров.


Если просто добавить Stateful - как вы описали - то будет такая же каша  как и со Stateless  бином.


ava
korian | 21.02.2013, 19:00 #
Цитата (Atum @  21.2.2013,  09:41 findReferencedText)
для Stateless  - должен быть уникальный счетчик для каждого пользователя на его сессию.



для s1Stateful    - будет каша в выводе -  если будет несколько клиентов и несколько браузеров.

Если это то, как должно быть - то вы перепутали их местами.

Цитата (Atum @  21.2.2013,  09:41 findReferencedText)
Если просто добавить Stateful - как вы описали - то будет такая же каша  как и со Stateless  бином.

Сессия создается? Если сессия не создается, то Stateful может работать как Stateless, потому как будет создаваться каждый раз.

Ну и вообще, какой контейнер и окружение используется?
ava
Atum | 21.02.2013, 20:40 #
Цитата (korian @ 21.2.2013,  19:00)
Сессия создается? Если сессия не создается, то Stateful может работать как Stateless, потому как будет создаваться каждый раз.




glassfish 3

jboss 7

что то вы лукавите по поводу Stateful  как Stateless.
ava
korian | 23.02.2013, 21:06 #
Короче я частично перепутал то, как оно работает с CDI.
В принципе, можно его и использовать:
https://vaadin.com/wiki/-/wiki/Main/Creatin...%20Applications
ava
Atum | 28.02.2013, 16:00 #
Есть такой вопрос ,а если использовать аннотации из Context & Dependency Injection


@Named
@SessionScoped

такой бин будет равняться


Stateful  бину ?
ava
korian | 01.03.2013, 03:57 #
Цитата (Atum @  28.2.2013,  15:00 findReferencedText)
 такой бин будет равняться 





Stateful  бину ?

С точки зрения времени жизни - да.
@SessionScoped - есть также в JSF, там можно перепутать импорт.

Для CDI - [@Named] @SessionScoped
Для JSF - @ManagedBean @SessionScoped
Зарегистрируйтесь или войдите, чтобы написать.
Фирма дня
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Участники
  korian   Atum
advanced
Отправить