EJB kontajner by mal manažovať zásobník SB inštancií takým spôsobom, aby čo najefektívnejšie obsluhoval požiadavky klientov. V závislosti od nastavenia a počtu požiadaviek sa kontajner dynamicky rozhoduje, kedy bude nová inštancia vytvorená, priradená klientovi, pasivovaná, aktivovaná alebo ukončená. V tomto článku sa pozrieme na životný cyklus stateless aj stateful session beanov.

Jednotlivé etapy životného cyklu sú rôzne pre stateless a stateful session bean. Ako asi správne predpokladáte, životný cyklus stateless SB je podstatne jednoduchší a preto začneme práve ním.

Špecifikácia EJB 2.x definuje pre SlSB iba dva stavy, pričom v jednom z nich inštancia zatiaľ neexistuje a v druhom stave je „method-ready„. Session objekt začína existovať vtedy, keď kontajner zavolá metódu newInstance asociovaného Class objektu reprezentujúceho vašu implementačnú session bean triedu. Po vytvorení inštancie kontajner zavolá jej metódy setSessionContext a ejbCreate. Keďže môžete deklarovať iba jednu samostatnú create metódu, tak vaša ejbCreate metóda by mala vyzerať nasledovne:

public void ejbCreate() throws CreateException {
 // sem vložte potrebnú inicializáciu, spoločnú pre všetkých klientov
}

Po ukončení behu ejbCreate metódy, je inštancia SlSB v stave method-ready. Keď klient zavolá biznis metódu patriacu referencii na komponentné rozhranie SlSB, kontajner vyberie voľnú inštanciu nachádzajúcu sa v spomínanom stave a deleguje to volanie na ňu. Po ukončení behu biznis metódy je inštancia vrátená do zásobníka a už viac nie je asociovaná s konkrétnym klientom. Rovnako ako volanie create metódy klientom nemusí nutne znamenať vytvorenie novej inštancie, ani volanie metódy remove nemusí automaticky znamenať zmazanie existujúcej inštancie.

Životný cyklus inštancie stateless session bean
Životný cyklus inštancie stateless session bean

Na rozdiel od SlSB má klient určitú možnosť ako ovplyvniť životný cyklus stateful session bean. Na začiatok je inštancia SfSB vytvorená v okamihu kedy klient zavolá create metódu home rozhrania konkrétneho beanu. Následne kontajner zavolá metódy newInstance, setSessionContext a korešpondujúcu metódu ejbCreate. Po ukončení tejto metódy sa inštancia nachádza v method-ready stave a klient obdrží referenciu na komponentné rozhranie SfSB. Následne môže klient zavolať požadovanú biznis metódu, a kontajner deleguje jej vykonanie inštancii SfSB, ktorá bola vytvorená špeciálne pre tohto klienta.

Ak sa kontajner rozhodne pasivovať SfSB inštanciu, ktorá je v method-ready stave, zavolá jej metódu ejbPassivate. V rámci tejto metódy by mala inštancia uvoľniť všetky obsadené zdroje. Následne môže inštancia opustiť tento stav dvoma spôsobmi, buď bude znova aktivovaná, alebo definitívne odstránená. V prvom prípade kontajner zavolá jej metódu ejbActivate a vráti inštanciu do method-ready stavu. V druhom prípade ak uplynie určitý timout (v závislosti od nastavenia), môže kontajner pasivovanú inštanciu definitívne odstrániť. O odstránenie inštancie SfSB môže požiadať aj priamo klient zavolaním jej metódy remove. Predtým ako je inštancia definitívne odstránená, zavolá kontajner jej metódu ejbRemove.

Životný cyklus inštancie stateful session bean
Životný cyklus inštancie stateful session bean

Ako pristupovať k iným EJB

Veľa session beans ktoré napíšete, bude potrebovať pristupovať k jednej alebo viacerým entity beanom. Spôsob akým sa to dá je deklarovať EJB referenciu v deployment deskriptore session beany pre každý entity bean, ku ktorému je potrebné pristupovať. Potom už môžete použiť túto referenciu na vyhľadanie home rozhrania danej entity. Napríklad session bean aukčného domu môže potrebovať predať požiadavku na vloženie novej ponuky tej správnej entitnej triede. Takýto deskriptor musí obsahovať nasledovné časti:

<ejb-jar>
 <enterprise-beans>
  <session>
   <ejb-name>AuctionHouse</ejb-name>
   
    <ejb-local-ref>
     <description>Táto EJB referencia je použitá na vyhľadanie konkrétnej aukcie.
     </description>
     <ejb-ref-name>ejb/EnglishAuction</ejb-ref-name>
     <ejb-ref-type>Entity</ejb-ref-type>
     <local-home>EnglishAuctionHome</local-home>
     <local>EnglishAuction</local>
    </ejb-local-ref>
   
  </session>
  
 </enterprise-beans>

</ejb-jar>

V rámci deployment deskriptora by bolo ešte treba vložiť podobnú referenciu na entitu zastupujúcu dražiteľa. S takto definovanými referenciami by implementácia metódy submitBid triedy AuctionHouseBean mohla vyzerať nasledovne.

public class AuctionHouseBean implements SessionBean {

 public String submitBid(double bidAmount, int auctionId, int bidderId)
  throws InvalidBidException, InvalidAuctionStatusException {
  try {
   // Získame home rozhranie EnglishAuction bean-u.
   EnglishAuctionHome auctionHome = getEnglishAuctionHome();
   // Získame home rozhranie Bidder bean-u.
   BidderHome bidderHome = getBidderHome();
   // Vyhľadáme špecifickú aukciu.
   EnglishAuction auction = auctionHome.findByPrimaryKey(new Integer(auctionId) );
   // Vyhľadáme špecifického dražiteľa.
   Bidder bidder = bidderHome.findByPrimaryKey( new Integer(bidderId) );
   // Vložíme novú ponuku do aukcie.
   return auction.submitBid(bidAmount, bidder);
  }
  catch (FinderException fe) {
   throw new InvalidBidException(„ID aukcie alebo dražiteľa je chybné!“);
  }
 }
 
 private EnglishAuctionHome getEnglishAuctionHome() {
  InitialContext initCtx = null;
  try {
   // Získame JNDI context.
   initCtx = new InitialContext();
   // Vyhľadáme home rozhranie pre EnglishAuction
   // definované ako EJB referencia v deployment
   // deskriptore.
   Object obj = initCtx.lookup( „java:comp/env/ejb/EnglishAuction“ );
   return (EnglishAuctionHome)obj;
  }
  catch (NamingException ex) {
   throw new EJBException(ex);
  }
  finally {
   // Zatvoríme JNDI InitialContext.
   try {
    if (initCtx != null) {
     initCtx.close();
    }
   }
   catch (Exception ex) {
    throw new EJBException(ex);
   }
  }
 }
 private BidderHome getBidderHome() {
  InitialContext initCtx = null;
  try {
   // Získame JNDI context.
   initCtx = new InitialContext();
   // Vyhľadáme home rozhranie pre Bidder
   // definované ako EJB referencia v deployment
   // deskriptore.
   Object obj = initCtx.lookup( „java:comp/env/ejb/Bidder“ );
   return (BidderHome)obj;
  }
  catch (NamingException ex) {
   throw new EJBException(ex);
  }
  finally {
   // Zatvoríme JNDI InitialContext.
   try {
    if (initCtx != null) {
     initCtx.close();
    }
   }
   catch (Exception ex) {
    throw new EJBException(ex);
   }
  }
 }

}

V budúcej časti sa pozrieme na deployment vytvorených session beanov, pričom by sme túto problematiku ukončili a povedali si niečo o poslednom type EJB – Message-Driven Beans.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Žádný příspěvek v diskuzi

Odpovědět