W tym artykule przyjrzymy się EJB - Enterprise JavaBeans. Technologia ta jest częścią specyfikacji Java EE. Poruszymy takie kwestie jak:
- czym jest EJB;
- jaka jest historia EJB;
- jakie są rodzaje EJB?
Krótka historia EJB
W 1996 roku, kiedy autor tego artykułu miał 5 lat, Java była już popularna wśród programistów. Powodem tego było przyjazne API, automatyczne zbieranie śmieci itp. Java znalazła szerokie zastosowanie w systemach odpowiedzialnych za backend. Jednak pomimo wszystkich uroków języka, programiści tamtych czasów potrzebowali pewnych funkcjonalności, które nie były jeszcze zaimplementowane w JDK. Potrzebami tymi były:- zapewnienie trwałości danych;
- integralność transakcji
- konkurencyjny dostęp do danych (kontrola wielowątkowa);
- i najprawdopodobniej coś innego.
Co to jest EJB
EJB w pewnym sensie jest terminem zbiorczym, który w zależności od kontekstu może oznaczać albo samą technologię Enterprise JavaBeans w ogóle, albo jakiś konkretny komponent oprogramowania Enterprise JavaBean (bean), który jest częścią technologii EJB. Definicja EJB jako technologii podana jest w Wikipedii: Enterprise JavaBeans (często używany również jako skrót EJB) to specyfikacja technologii służącej do pisania i obsługi komponentów serwerowych zawierających logikę biznesową. Jest częścią Java EE. Technologia ta jest zwykle używana, gdy logika biznesowa wymaga co najmniej jednej z następujących usług, a często wszystkich:- wsparcie trwałości danych: dane powinny być bezpieczne nawet po zatrzymaniu programu. Najczęściej osiągane przy użyciu bazy danych;
- obsługa transakcji rozproszonych;
- wsparcie dla równoległej modyfikacji danych i wielowątkowości;
- obsługa wydarzeń;
- obsługa nazewnictwa i katalogów (JNDI);
- bezpieczeństwo i ograniczenie dostępu do danych;
- obsługa automatycznej instalacji na serwerze aplikacji;
- zdalny dostęp.
typy EJB
Podsumujmy. EJB to zwykła klasa Java oznaczona jedną ze specjalnych adnotacji. Takie klasy nazywane są fasolami. W zależności od tego, jaką adnotacją oznaczona jest klasa, będzie ona reprezentatywna dla tego lub innego typu EJB (fasola). Istnieją trzy główne rodzaje fasoli:- Fasola sterowana wiadomościami (fasola sterowana wiadomościami);
- Entity Beans – zdefiniowane w specyfikacji JPA (Java Persistence API) i służące do przechowywania danych;
- Fasola sesyjna.
- bezpaństwowy (bez stanu);
- stanowy (z obsługą bieżącego stanu sesji);
- singleton (jeden obiekt dla całej aplikacji; począwszy od EJB 3.1).
Fasola sesyjna
Fasola sesyjna, czyli fasola sesyjna, to specyficzny rodzaj fasoli. Hermetyzują logikę biznesową, którą klient może programowo wywołać, wywołując metody komponentu bean. Wywołanie metody może wykonać:- lokalnie przez inną klasę w tej samej maszynie JVM, w której znajduje się komponent sesyjny;
- zdalnie, przez sieć, z innej maszyny JVM, przy użyciu technologii Java RMI (Remote Method Invocation).
@Stateless
. Podajmy przykład poniżej:
import javax.ejb.Stateless;
@Stateless
public class StatelessEjbExample {
public String sayHi() {
return "Hi, I'm Stateless EJB!";
}
}
Zbiorniki sesji obsługujące bieżący stan sesji (Stateful) zachowują informacje o swoim stanie pomiędzy wywołaniami do niej od tego samego klienta i kończą swoje istnienie na wyraźne żądanie klienta. Osiąga się to dzięki temu, że stanowe komponenty bean są unikalne dla każdego klienta. Przykładowym zadaniem, za które może odpowiadać tego typu fasola, jest bieżąca aktualność koszyka w sklepie internetowym dla każdego użytkownika. Cyklem życia tych ziaren zarządza kontener EJB. Te ziarna są również niszczone, gdy klient wychodzi. Takie fasolki są również dość łatwe do stworzenia. Jest to klasa Java oznaczona adnotacją Stateful
. Przykład poniżej:
import javax.ejb.Stateful;
@Stateful
public class StatefulEjbExample {
public String sayHi() {
return "Hi, I,m Stateful EJB";
}
}
Zbiorniki sesji Singleton są inicjowane raz w ciągu życia aplikacji i istnieją przez cały okres istnienia aplikacji. Takie komponenty fasoli są przeznaczone do sytuacji, w których jeden stan musi być współużytkowany przez wszystkich klientów. Podobnie jak w przypadku komponentów bean bezstanowych, w przypadku komponentów autonomicznych programista musi upewnić się, że komponenty bean mają środowisko bezpieczne dla wątków. Podajmy przykład fasoli Singleton, którą można stworzyć równie łatwo, jak jej odpowiedniki, o których mówiliśmy powyżej. Łatwo się domyślić, że jest to klasa Java z adnotacją @Singleton
. Jednak w tym przypadku trzeba zachować ostrożność. Istnieją dwie adnotacje, identyczne w składni, ale różne w celu i umieszczone w różnych pakietach:
- javax.ejb.Singleton
- javax.inject.Singleton
javax.ejb
. Przykład poniżej:
import javax.ejb.Singleton;
@Singleton
public class SingletonEjbExample {
public String sayHi() {
return "Hi, I'm Singleton EJB!";
}
}
Fasola sterowana wiadomościami
Message Driven Beans, czyli MDB, czyli komponenty Beans sterowane komunikatami, implementują pewną logikę biznesową, np. komponenty Bean sesji. Ale w przeciwieństwie do swoich krewnych, MDB ma jedną istotną różnicę. Klienci nigdy nie wywołują bezpośrednio metod MDB. Takie komponenty bean najczęściej pełnią funkcję słuchaczy komunikatów JMS (Java Message Service) i służą do organizowania asynchronicznej wymiany komunikatów pomiędzy częściami systemu. Przykładem takiego komunikatu może być żądanie dostarczenia zapasów z zautomatyzowanego systemu sprzedaży detalicznej do systemu zarządzania dostawami. Poniżej znajduje się przykład komponentu bean MDB. W przeciwieństwie do ziaren sesyjnych, jego tworzenie jest nieco bardziej interesujące:import javax.annotation.Resource;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
@MessageDriven(mappedName = "jms/TestQueue")
public class MessageDrivenEjbExample implements MessageListener {
@Resource
private MessageDrivenContext messageDrivenContext;
public void onMessage(Message message) {
try {
if (message instanceof TextMessage) {
TextMessage msg = (TextMessage) message;
msg.getText();
}
} catch (JMSException e) {
messageDrivenContext.setRollbackOnly();
}
}
}
Adnotacja MessageDriven
sprawia, że nasza klasa MDB jest fasolą. Wewnątrz adnotacji za pomocą JNDI (o JNDI przeczytasz tutaj ) zostaje określona nazwa dystrybucji JMS, której słuchaczem stanie się nasza klasa. Dodatkowo nasza klasa implementuje interfejs MessageListener
i jego metodę onMessage
. Ta metoda zostanie wywołana, gdy z kolejki/dystrybucji nadejdzie wiadomość o nazwie zdefiniowanej w adnotacji MessageDriven
.
Fasola jednostek
Częścią technologii EJB jest specyfikacja JPA. JPA, czyli Java Persistence API, to specyfikacja zapewniająca mapowanie obiektowo-relacyjne (ORM) obiektów Java (entity bean) oraz udostępniająca interfejs API do przechowywania, pobierania i zarządzania takimi obiektami. JPA umożliwia reprezentowanie danych z bazy danych jako obiektów Java, a także zapisywanie obiektów Java jako rekordów w bazie danych. Nie każda klasa może pełnić rolę takiego obiektu, ale fasola Entity. Entity Bean to klasa Java reprezentująca tabelę w bazie danych. Wyświetlanie (mapowanie) odbywa się poprzez zastosowanie specjalnych adnotacji. Za ich pomocą porównuje się klasę Java z tabelą w bazie danych, a także pola klasy Java porównuje się z polami tabeli bazy danych. Oto przykład komponentu bean Entity z komentarzami w kodzie:@Entity // Делает данный класс Entity бином
@Table(name = "employee") // "Связывает" данный класс с таблицей employee в БД
public class Employee implements Serializable {
@Id // Говорит о том, что поле ниже является первичным ключом
@GeneratedValue(strategy = GenerationType.AUTO) // Определяет тип генерации значений первичного ключа
private int id;
@Column(name="name") // "Связывает" поле ниже с полем name в таблице employee в БД
private String name;
@Column (name="age") // "Связывает" поле ниже с полем age в таблице employee в БД
private int age;
// getters and setters...
}
Warto zaznaczyć, że tego typu fasolę warto studiować jedynie w kontekście studiowania specyfikacji JPA.
Pisanie aplikacji: EJB HelloWorld
W tej sekcji napiszemy małą aplikację Java EE HelloWorld, którą wdrożymy na serwerze GlassFish. Przed przeczytaniem tego artykułu zdecydowanie zaleca się przeczytanie artykułu na temat konfigurowania środowiska lokalnego .-
Utwórz nowy projekt Maven w IntelliJ IDEA.
Plik -> Nowy -> Projekt...
-
Kliknij Następny .
-
Wypełnij parametry projektu Maven:
-
Kliknij Zakończ
-
Projekt został stworzony i ma następującą strukturę:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.javarush.lectures</groupId>
<artifactId>ejb_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
</dependencies>
</project>
Następnie możesz przejść do kodu Java. Nasza aplikacja będzie najprostsza. Będziemy mieć 1 serwlet i 1 EJB. Będzie to bezstanowy komponent sesyjny. Wewnątrz EJB zdefiniujemy tylko 1 metodę, która zwróci ciąg „Hello World”. Na początek utwórzmy pakiet com.javarush.lectures
. Następnie w pakiecie com.javarush.lectures
utworzymy nasz komponent bean - DemoEJB. Kod fasoli podano poniżej:
import javax.ejb.Stateless;
@Stateless
public class DemoEJB {
public String helloWorld() {
return "Hello world!";
}
}
Jak powiedziano wcześniej, wszystko jest dość proste. Następnym krokiem będzie utworzenie serwletu, który przekaże wartość z komponentu EJB w odpowiedzi na żądanie HTTP. Warto zauważyć, że serwlety nie są tematem tego artykułu, ale nadal będziesz musiał ich użyć, aby zademonstrować EJB. Aby to zrobić, utwórzmy nowy serwlet DemoServlet
w tym samym pakiecie co EJB. Jego kod znajduje się poniżej:
@WebServlet("/helloWorld")
public class DemoServlet extends HttpServlet {
@EJB
private DemoEJB ejb;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write(ejb.helloWorld());
}
}
Oto kilka krótkich komentarzy na temat kodu. Streszczenie @WebServlet("/helloWorld")
- definiuje naszą klasę jako serwlet, który będzie przetwarzał żądania HTTP do punktu końcowego /helloWorld
. Nasza klasa ma jedno pole - DemoEJB ejb
. To jest nasza fasola zdefiniowana wcześniej. Adnotacja nad polem klasy — @EJB
wykonuje wstrzykiwanie zależności (DI). Te. W razie potrzeby zmienna ejb jest automatycznie inicjowana nową instancją. Nasza klasa jest potomkiem HttpServlet i zastępuje jedną z metod nadklasy - doGet
. Ta metoda przetwarza żądania HTTP GET i przyjmuje dwa parametry - HttpServletRequest
i HttpServletResponse
. HttpServletRequest
służy do uzyskania informacji o przychodzącym żądaniu HTTP. HttpServletResponse
potrzebne do wygenerowania odpowiedzi na żądanie. Wewnątrz metody pobieramy obiekt PrintWriter
z obiektu odpowiedzi ( HttpServletResponse
), używając metody getWriter()
. Następnie możemy zapisać pewną wartość do wynikowego obiektu za pomocą metody write
. I właśnie tego używamy, wpisując do PrintWriter
obiektu -a wartość uzyskaną ze zdefiniowanego przez nas EJB (wartością jest ciąg „Hello World!”). Klient, który wysłał żądanie HTTP, otrzyma tę wartość w odpowiedzi na swoje żądanie. Kolejnym krokiem jest uruchomienie aplikacji na serwerze GlassFish Java EE. W tym celu utworzymy nową konfigurację, zgodnie z opisem w artykule dotyczącym konfigurowania środowiska lokalnego . Poniżej znajduje się zrzut ekranu gotowej konfiguracji dla bieżącego projektu. Przed uruchomieniem upewnij się, że masz zainstalowany serwer GlassFish: Po utworzeniu konfiguracji startowej uruchom aplikację za pomocą menu Uruchom -> Uruchom 'ejb_demo' lub za pomocą skrótu Shift+F10 . Po uruchomieniu możesz zobaczyć jego logi: A także przeglądarkę, która się otworzy: Wszystko to wskazuje, że aplikacja działa zgodnie z przeznaczeniem.
Wniosek
W tym artykule zapoznaliśmy się z EJB - Enterprise JavaBeans. Rozważaliśmy takie kwestie jak:- Co to jest EJB?
- Historia EJB
- Różne typy EJB
- Fasola sterowana wiadomościami (fasola sterowana wiadomościami);
- Entity Beans – zdefiniowane w specyfikacji encji JPA (Java Persistence API) i służące do przechowywania danych;
- Ziarna sesji:
- bezpaństwowy (bez stanu)
- stanowy (z obsługą bieżącego stanu sesji)
- singleton (jeden obiekt dla całej aplikacji; począwszy od EJB 3.1)
GO TO FULL VERSION