Enterprise Java Beans
Enterprise Java Beans 3 (EJB3) jsou řízené, serverové komponenty umožňující modulární tvorbu podnikových aplikací. Specifikace EJB3 je součástí množiny aplikačního programového rozhraní (API) definující Java Enterprise Edition (Java EE). EJB3 vychází z vlastností klasických Java Beans. Cílem EJB je oddělit business logiku aplikace od prezentační (viz např. JSP) a persistentní vrstvy (viz CRUD operace), ale také zajistit předpoklady pro integraci s ostatními technologiemi – JMS, JNDI a CORBA. Vývojáři podnikových systémů tak mohou využívat výhody plynoucí z užití EJB – znovu-použitelnost kódu, oddělení logiky aplikace, transakční zpracování, bezpečnost, jednodušší testování a integrace apod.
Ve specifikaci EJB je také detailněji popsáno, jakým způsobem má aplikační server spolu s EJB kontejnerem poskytovat základní funkcionalitu (persistenci přes Java Persistence API, transakční zpracování, řízení souběžného přístupu, události pomocí JMS, jmenné a adresářové služby JNDI, bezpečnost – JCE a JAAS, nasazení softwarových komponent na aplikační server, vzdálené volání procedur pomocí RMI-IIOP, zpřístupnění business metod ve formě webových služeb).
EJB kontejner
Představuje dedikovaný virtuální prostor v aplikačním serveru, kam se nasazují EJB komponenty. Kontejner řeší zejména následující problematiku[1]:
- Komunikace se vzdáleným klientem – zjednodušuje komunikaci mezi klientem a aplikací
- Dependency injection – zajišťuje naplnění deklarovaných proměnných (datových atributů) např. dalšími EJBeany, JMS, datovými zdroji (zejména SQL připojení), atd.
- Řízení stavu – kontejner udržuje v paměti stavy jednotlivých stavových (stateful) beanů a tím i vzdálený stav u klienta, kterému se jeví stav jakoby uložen lokálně
- Pooling – vytváření poolu instancí pro bezstavové beany a message-driven beany (MDB) viz dále
- Řízení životního cyklu – stará se o vytváření, inicializaci a destrukci instancí beanů a další události
- Messaging – umožňuje MDB poslouchat na JMS destinacích a konzumovat zprávy a zároveň odstiňuje programátora od komplikovaného API Java Messaging Service (JMS)
- Management transakcí – beany deklarují transakční vlastnosti metod, kontejner řeší commit a rollback
- Bezpečnost – deklarace přístupů na úrovni tříd a metod
- Podpora souběžného zpracování – vývojář nemusí řešit problémy synchronizace souběžných přístupů ke sdíleným datům
- Správa interceptorů – komponenty umožňující odchytávat okamžik před a po volání metody
- Asynchronní volání metod – od EJB 3.1 viz dále MDB
Embedded kontejner
Nabízí možnost spouštět EJB aplikace v prostředí Java SE. Usnadňuje testování a ladění, ale podporuje jen podmnožinu EJB Lite (bez MDB, vzdálených rozhraní, webových služeb, …).
Rozhraní
Rozhraní slouží pro definování metod, které bude muset bean implementovat a poskytovat navenek pro manipulaci s jeho datovými atributy. Každý EJB musí implementovat aspoň jedno z níže uvedených rozhraní:
- Lokální rozhraní – pokud není žádné rozhraní u třídy definováno, má se za to, že bean je lokálního typu, což v praxi znamená, že běží a jeho metody jsou volány pouze v rámci jednoho Java Virtual Machine. Anotuje se jako
@Local
buď přímo před deklarací třídy beanu nebo v deklaraci souboru rozhraní. - Vzdálené rozhraní – označeno anotací
@Remote
se používá při volání metod takovéhoto EJB (běžícího obvykle v JVM na aplikačním serveru) z jiného vzdáleného JVM (obvykle JVM u klienta). K volání metod slouží distribuovaný protokol (obvykle RMI-IIOP). Tímto způsobem lze vytvářet plnohodnotné klientské aplikace, které nejsou vázané pouze na webový prohlížeč. - Endpoint rozhraní (též Service endpoint interface) – slouží k označení rozhraní přístupného pro webové služby (SOAP). Anotováno
@javax.jws.WebService
. - Message rozhraní – implementováno Message Driven Beany. Rozhraní MD beanu je voláno Java Message Službou, když je doručena nová zpráva do fronty/topiku nebo jiným Message Oriented Middlewarem. Rozhraní obsahuje jednu metodu
onMessage(TypListeneru)
– typ listeneru závisí na konkrétním typu middleware, pro JMS je tojavax.jms.MessageListener
.
Typy EJB
V EJB kontejneru nalezneme dva druhy EJB – Session Beans a Message Driven Beans.
Stateless Session Beans (bezstavové beany)
Bezstavové beany neuchovávají stav relevantní pro klienta mezi obsluhou jeho jednotlivých požadavků. Pro obsloužení každého požadavku klienta je mu vždy na serveru přidělena samostatná instance, která je vyhrazena pouze tomuto klientovi v rámci jednoho daného požadavku – z tohoto důvodu jsou bezstavové beany přirozeně vláknově bezpečné. V rámci jednoho volání metody (požadavku) lze použít i datové atributy instance beanu, ale není zaručeno, že se jejich obsah při dalším volání nezmění. Bezstavové beany se na serveru obvykle sdružují v poolu, ze kterého jsou odebírány pro obsloužení požadavku a následně se do něj zpět vrací. Třída představující bezstavový bean musí být anotována @Stateless
Životní cyklus stateless beanu
Cyklus beanu začíná ze stavu „neexistence“ vytvořením nové instance a jejím zařazením do poolu na serveru. Při vytváření instance server do beanu injektuje případné reference a volá metodu anotovanou @PostConstruct
, pokud taková existuje, která může sloužit například k otevření JDBC připojení. Když je bean ve stavu method-ready-pool může obsluhovat klientské požadavky (poskytovat své business metody). V případě, že se server rozhodne uvolnit paměť zabranou beany nebo je ukončován standardním způsobem, volají se případné metody rušeného beanu anotované @PreDestroy
, které slouží jako inverzní operace k post-constructu (tedy např. uzavírání databázového spojení). Stateless bean může skončit svou existenci také vyhozením systémové výjimky, která způsobí okamžité odstranění beanu z paměti (nevolá se @PreDestroy
).
Stateful Session Beans (stavové beany)
Jsou objekty, které si uchovávají svůj stav mezi voláním metod (obsluhy požadavků klienta) v rámci jedné session. Pro každého unikátního klienta se vytvoří v paměti na serveru samostatná instance stavového session beanu, která patří pouze tomuto klientovi a při dalším volání metod se použije vždy stejný objekt obsahující data z předchozí interakce klienta. Stavový bean si můžeme představit jako prodlouženou ruku klienta na serveru. V rámci životního cyklu stavového beanu může dojít k jeho pasivaci (uložení pomocí persistentní vrstvy) prováděnou kontejnerem za účelem uvolnění paměti na serveru. Pouze ve stavových beanech lze použít tzv. JPA rozšířený JPA persistence kontext (JPA). Doba života tohoto kontextu je svázána s životem stavového beanu, na rozdíl od implicitního transakčního kontextu, jehož doba života je vymezena transakcí (typicky voláním business metody). Třída představující stavový bean musí být anotována @Stateful
Životní cyklus stavového beanu
Životní cyklus stavového beanu je podobný bezstavovému. Vytváření, rušení beanu a volání metod stateful beanu je shodné jako u stateless. Rozdíl nastává, pokud se server rozhodne uvolnit část prostředků z vlastní paměti, tehdy dochází k pasivaci stavových beanů tj. jejich uložení v serializované podobě na server a jejich odpojení od SessionContextu (přesto ale zůstávají v ExtendedSessionContextu; viz EntityManager a SessionContext). Před provedením pasivace server vyhledá a zavolá metodu beanu anotovanou @PrePasivate
(resp. @PostActivate
se zavolá po obnovení beanu). Bean může také přestat existovat, pokud vyprší jeho časová životnost na serveru (timeout) nebo nastane-li systémová výjimka (opět jako u stateless EJB).
Singleton Session Beans
Jsou business objekty s globálně sdíleným stavem. Synchronizovaný přístup k tomuto typu objektů může být řízen buď kontejnerem (Container-managed concurrency) anebo samotným beanem (bean-managed concurrency) pomocí anotace @Lock
a příslušným parametrem zámku pro čtení nebo zápis při volání metod. Pomocí anotace @Startup
je možné vytvářet instance sinlgetonových beanů již při startu EJB kontejneru a načítat takto jejich obsah. Tento přístup je vhodný při načítání statických hodnot (obvykle číselníků – např. seznamy PSČ), čímž dochází k úsporám systémových prostředků a také času při opakovaném načítání stejných hodnot z databáze v pozdější fázi běhu aplikace (kešování). Třída singletonu je označena anotací @Singleton
Message Driven Beans
Zprávami řízené beany byly navrženy ve specifikaci EJB 2.0 (od J2EE 1.3). MDB spojuje Java Message Service (JMS) s EJB a tak vzniká nový typ beanu ovládající asynchronní JMS nebo jiné typy zpráv. Hlavní charakteristikou MDBeanů je především jejich asynchronní chování. MDB tedy slouží k obsluze operací, které nevyžadují okamžitou odpověď. Tento typ beanů se může registrovat k JMS, k message queues nebo message topics, které byly přidány v EJB 2.0, aby umožnily událostně-řízené zpracování uvnitř EJB kontejneru.
- Poznámka: Od EJB v. 3.1 lze jako asynchronní označit přímo některou třídu nebo metodu (anotace
@Asynchronous
), taková metoda pak nevrací přímo výsledek (návratový typvoid
), ale pomocí určitých konstruktů si ho lze později vyzvednout (vizjava.util.concurrent.Future
).
Příklady
Deklarace Enterprise Java Beanu s lokálním a vzdáleným rozhraním:
@javax.ejb.Stateless
@javax.ejb.Local (MyLocalInterface.class)
@javax.ejb.Remote (MyRemoteInterface.class)
public class MyStatelessBean implements MyLocalInterface, MyRemoteInterface { ...implementace metod rozhraní v beanu... }
kde MyLocalInterface a MyRemoteInterface jsou vlastní deklarovaná rozhraní, která bean musí implementovat. Anotace @Local může být uvedena přímo v deklaraci rozhraní (viz níže), anebo v záhlaví deklarace beanu, kam se doplní příslušný typ rozhraní (.class
).
@javax.ejb.Local
public interface MyLocalInterface {
public void addCustomer(Customer customer);
//... další metody rozhraní
}
Reference
V tomto článku byl použit překlad textu z článku Enterprise JavaBean na anglické Wikipedii.
- ŠLAJCHRT, Z.: Vývoj podnikových aplikací na platformě Java – část 4. [online] 2010; http://java.vse.cz/wiki/uploads/4it447/4it447-prednaska4.ppt
Externí odkazy
- Java EE 6; http://java.sun.com/javaee/6/docs/tutorial/doc/bnblr.html
- TRONÍČEK, Z.: Enterprise Java Beans & Java Persistence API, 10. 4. 2009, (záznam z přednášky); https://web.archive.org/web/20110704220257/http://video.google.com/videoplay?docid=6115836978088726875
- EBENLENDR, T.: Java 2 Enterprise Edition, 12.1. 2006; https://web.archive.org/web/20100329104457/http://artax.karlin.mff.cuni.cz/~ebik/nju/linuxem/J2EE/J2EE.html