Enterprise JavaBean
Transkrypt
Enterprise JavaBean
Enterprise JavaBean EJB 2.x oraz zmiany w standardzie dla EJB 3.0 Michał Stanek Plan prezentacji Czym jest EJB Architektura aplikacji J2EE oraz kontener EJB Typy komponentów JavaBean EJB 1.0, EJB 2.x Wady EJB 2.x zmiany wprowadzone w EJB 3.0 Kilka przykładów Czym jest EJB EJB jest częścią specyfikacji/platformy J2EE EJB komponent po stronie serwera EJB enkapsuluje logikę/obiekty biznesowe EJB ma uprościć proces wytwarzania oprogramowania EJB – to również cienki klient Możliwość zakupienia gotowych komponentów EJB od innych dostawców Architektura Aplikacji J2EE Architektura aplikacji J2EE Kiedy używa się EJB Aplikacja ma być „skalowalna” ( lokalizacja komponentów EJB jest transparentna dla klienta ) W celu zapewnienia integralności danych musimy wprowadzić transakcje Istnieje wiele różnorodnych klientów naszej aplikacji. Kontener EJB Czym zajmuje się Kontener EJB Izoluje EJB przed bezpośrednimi wywołaniami z zewnątrz (wszystkie wywołania są przechwytywane przez kontener) Zapewnia automatycznie: Persystencję obiektów Transakcje Bezpieczeństwo Kontener zarządza jednocześnie wieloma EJB (podobnie jak kontener servletów) Rodzaje EJB Enterprise JavaBean Session Bean Stateless Stateful Entity Bean CMP BMP Message-Driven Bean Session EJB Reprezentuje pojedynczego klienta aplikacji. Session Bean nie jest dzielony pomiędzy klientami. Session Bean nie jest persystentny ( istnieje second storage) Kiedy klient kończy połączenie Session Bean jest zwalniany (pooling, zwolnienie zasobu) Stateless Session Bean Bean nie przechowuje stanu pomiędzy kolejnymi wywołaniami klienta W ramach wywołania bean może mieć stan, może korzystać z Entity Bean, zewnętrznych zasobów, itp… Nie są nigdy zapisywane przez kontener Są „lżejsze” od Stateful Session Bean Statefull Sesion Bean Pomiędzy kolejnymi wywołaniami klienta zachowywany jest stan „konwersacji” Jest bardziej obciążający dla kontenera Entity EJB Entity Bean reprezentuje obiekt biznesowy. Entity Bean jest z natury persystentny (z reguły obiektowi Entity Bean odpowiada tabela w Relacyjnej bazie danych). Posiada klucz główny Może pozostawać w związkach z innymi Entity Beans Może być dzielony pomiędzy wielu klientów CMP i BMP Entity Bean Bean Managed Persistency: Musimy sami oprogramować persystencję obiektu Container Managed Persistency: Kontener zajmuje się zapisem i odczytem beana z bazy danych Nie trzeba pisać nawet jednej linijki w SQL’u Zapewniamy większą przenośność naszego Beana Aby zapewnić persystencję musimy dostarczyć jedynie Entity Bean Abstract Schema Abstract Schema Definiuje jakie pola w Entity Bean są persystentne Określa związki Entity Bean z innymi obiektami Musimy podać nazwę Abstract Schema w deskryptorze wdrożenia Dla CMP Bean musimy za pomocą EJB QL zdefiniować każdą metodę find (oprócz findByPrimaryKey) Kiedy używać Entity Bean Bean reprezentuje obiekt biznesowy, a nie procedurę ( CreditCardBean, CreditCardVeriferBean) Stan obiektu musi pozostać persystentny Message Driven Bean W odróżnieniu do poprzednich pozwala przetwarzać komunikaty asynchronicznie Działa podobnie do Listnera zdarzeń – otrzymuje JMS message zamiast event Komunikat może być wysłany przez dowolny komponent J2EE (klienta, Enterprise JavaBeana, komponent Webowy) Klient nie wywołuje M-D Beana przez jakikolwiek interfejs. Każdy M-D Bean jest równoważny (jest bezstanowy) Jest efektywniejszy niż inne Beany – nie jest podejmowana konwersacja z serwerem. Ogólny proces tworzenia komponentu EJB Przygotowanie kodu źródłowego klasy Java, reprezentującej komponent EJB Utworzenie dwóch interfejsów Java, reprezentujących punkty kontaktu świata zewnętrznego z komponentem EJB: interfejs Home, służący do zarządzania cyklem życia komponentu EJB interfejs Remote/Local, służący do wywoływania metod logiki biznesowej komponentu EJB Przygotowanie XML-owego pliku konfiguracyjnego - deskryptora instalacji (Deployment Descriptor) Kompilacja całego przygotowanego kodu Java i utworzenie z niego pliku JAR/EAR o specjalnej wewnętrznej strukturze katalogów Umieszczenie przygotowanych plików w systemie plików serwera aplikacji; zarejestrowanie komponentu EJB Implementacja EJB Tworzenie Beana public interface Calculator extends EJBObject { int add (int a, int b) throws RemoteException; int subtract (int a, int b) throws RemoteException; } public interface CalculatorHome extends EJBHome { Calculator create() throws CreateException, RemoteException; } Tworzenie Beana public class CalculatorBean implements SessionBean { private SessionContext ctx; public void setSessionContext(SessionContext s) {ctx = s;} public void ejbCreate() {} public void ejbActivate () {} public void ejbPassivate () {} public void ejbRemove () {} public int add (int a, int b) { return a + b; } public int subtract (int a, int b) { return a – b; } } Tworzenie Beana <session> <ejb-name>CalculatorEJB</ejb-name> <home>com.example.CalculatorHome</home> <remote>com.example.Calculator</remote> <ejb-class>com.example.CalculatorBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> ... Przykładowy deskryptor wdrożenia Historia EJB EJB 1.0 XML-owy deskryptor wdrożenia Transakcje na poziomie metod, zabezpieczenia Brak asocjacji CMP zależne od kontenera Specyficzna deklaracja „finderów” Historia EJB EJB 2.x: CMR dla asocjacji Standaryzacja deskryptora wdrożenia dla CMP Wprowadzenie EJB QL Dodano Message Driven Bean Wady EJB 2.x „Brzydki” styl programowania – javax.ejb Bardzo złożony deskryptor wdrożenia Pomieszana implementacja sprawdzanych oraz nie sprawdzanych wyjątków Brak polimorfizmu Brak możliwości testowania poza kontenerem EJB QL – zbyt ograniczony ( brak agregacji/projekcji, brak outer-join’a, brak paginatora … ) Założenia EJB 3.0 Redukcja liczby generowanych artefaktów Eliminacja konieczności dostarczenia deskryptora wdrożenia Umożliwienie generowania interfejsów bezpośrednio z klasy Beana Uproszczenie tworzenia Enterprise JavaBean Eliminacja implementowanych interfejsów Założenia EJB 3.0 Uproszczenie tworzenia CMP Entity Bean Wprowadzenie dziedziczenia i polimorfizmu Rozszerzenie języka EJB QL m.in. o: Podzapytania Zapytania dynamiczne Projection Explicit inner oraz outer join Group by, Having Wsparcie dla natywnych wywołań SQL EJB 3.0 – Stateless Session Bean @Remote public interface Calculator { public int add(int x, int y); public int subtract(int x, int y); } @Stateless public class CalculatorBean implements Calculator { public int add(int x, int y) { return x + y; } public int subtract(int x, int y) { Return x – y; } } Stateless + generowany interfejs @Stateless public class CalculatorBean implements Calculator { public int add(int x, int y) { return x + y; } public int subtract(int x, int y) { Return x – y; } } Deskryptor wdrożenia Co zrobiliśmy? Eliminacja Interfejsu domowego(Home Interface) Obiekt jest zwykłym obiektem POJO (Plain Old Java Object) Tylko jeden artefakt Możliwość automatycznego generowania interfejsu Łatwość testowania za pomocą JUnit Simpliefied Entity Bean @Entity(table="Aukcja") public class Aukcja { @PK (column="AukcjaID", generator="sequence") private Long id; @Attribute private String opis; @OneToMany (inverse="auction" order-by="data") private Set<Rachunek> rachunek = new HashSet(); @ManyToOne (fk="sprzedawcaId") private User sprzedawca @Attribute(formula="Select Max(R.Suma) from Rachunek R" + "where R.AukcjaID = AuctionID") private BigDecimal maxSumaRachunku; public BigDecimal getMaxSumaRachunku() { return maxSumaRa } } Zalety … Uproszone projektowanie oraz programowanie Możliwość użycia obiektów poza kontenerem Łatwość testowania Usunięcie konieczności wykorzystywania wzorca projektowego DTO (Data Transfer Object) BMP – jest już w zasadzie bezcelowy Mapowanie O/R oraz EJB QL Użycie metadanych do określenia mapowania Wprowadzenie polimorfizmu i dziedziczenia: Table per class Table per class hierarchy Rozszerzenie możliwości EJB QL m.in. o: Bulk update i delete Projection Group by, Having Podzapytania Bulk update/delete DELETE FROM Klient k WHERE k.status = „nieaktywny” UPDATE Klient k SET k.status = „nieaktywny” WHERE c.zamowienia=0 Podzapytania SELECT dobryKlient FROM Klient dobryKlient WHERE dobryKlient.zamowienia < ( SELECT avg(k.zamowienia) FROM Klient k ) Podsumowanie Znaczna ewolucja poczynając od EJB 1.0 a kończąc na EJB 3.0 Uproszczenie modelowania złożonych systemów. Uniezależnienie się od konkretnych kontenerów serwletów. Skrócenie czasu wytwarzania oraz projektowania aplikacji. Łatwość testowania (możliwość pracy wg. Metodyki Test Driven Development) Resin – kontener EJB 3.0 Literatura The J2EE™ 1.4 Tutorial JSR 220: Enterprise JavaBeansTM,Version 3.0 - EJB 3.0 Simplified API JSR 220: Enterprise JavaBeansTM,Version 3.0 - Persistence API From EJB to Hibernate to EJB 3 – Gavin King (Jboss inc.) EJB 3.0 Work in progress – Linda De Michiel (EJB 3.0 Spec Lead) Literatura - książki Ed Roman – „Mastering Enterprise JavaBean 2nd edition” Richard Monson-Haefel – „EJB 3RD EDITION”