JavaRush /Blog Java /Random-PL /Przedstawiamy EJB
Анзор Кармов
Poziom 31
Санкт-Петербург

Przedstawiamy EJB

Opublikowano w grupie Random-PL
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?
Napiszemy także małą aplikację HelloWorld przy użyciu EJB i serwletów. Przedstawiamy EJB - 1Ten artykuł będzie przydatny dla czytelników, którzy zaznajomili się z Java SE i zaczynają uczyć się Java EE. Aby w pełni zrozumieć praktyczną część tego artykułu, zaleca się najpierw przeczytać artykuł „ Konfigurowanie środowiska lokalnego ”.

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.
Wszystko to doprowadziło do naturalnego wzrostu populacji rodzimych, samodzielnie pisanych, zamkniętych bibliotek. Innymi słowy, każdy zaspokajał swoje potrzeby najlepiej jak potrafił. Tak było do czasu, gdy IBM przedstawił hasło: „Każdy powinien zaspokajać swoje potrzeby w ten sam sposób” i w 1997 r. udostępnił specyfikację Enterprise Java Bean (EJB). To właśnie umożliwiło ujednolicenie procesu rozwoju i przeniesienie rozwiązań typowych problemów (opisanych powyżej jako potrzeby) do frameworka. Firma Sun adaptowała pomysł IBM przez 2 lata i w 1999 r. opublikowała specyfikację EJB 1.0. W ten sposób narodziła się ta technologia, która zostanie omówiona dalej w bardziej praktycznym duchu.

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.
Wymienione powyżej usługi stanowią niewątpliwą zaletę technologii EJB. Kolejną zaletą jest to, że wszystko wymienione powyżej działa od razu po wyjęciu z pudełka. Te. programista nie musi myśleć o obsłudze transakcji rozproszonych. Programista musi jedynie pomyśleć o logice biznesowej, którą aktualnie próbuje wdrożyć. EJB jako specyficzny komponent oprogramowania to klasa Java z jedną lub większą liczbą adnotacji ze specyfikacji EJB, która zawiera część logiki biznesowej aplikacji. Adnotacje ze specyfikacji EJB nadają oznaczonej klasie pewne moce, moce i supermoce. Przeczytaj więcej na ten temat poniżej.

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.
Te ostatnie (fasola sesyjna) dzielą się na kilka podtypów:
  • 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).
Przedstawiamy EJB - 2Poniżej przyjrzymy się bardziej szczegółowo każdemu rodzajowi fasoli.

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).
Słowo „sesja” oznacza, że ​​komponent bean jest dostępny tylko wtedy, gdy serwer wykonuje określone zadanie i ulega nieodwracalnemu zniszczeniu w przypadku awarii lub wyłączenia serwera. Cyklem życia instancji session bean steruje kontener EJB (więcej o kontenerach EJB przeczytasz w pierwszym wykładzie z tej serii ). Bezstanowe komponenty sesyjne nie przechowują informacji o swoim stanie. Tego typu komponent może być używany przez różnych klientów. Bezstanowe komponenty bean służą do implementacji procesów biznesowych, które można wykonać w jednej operacji. Na przykład sprawdzenie historii kredytowej klientów. Ponieważ z pojedynczej instancji komponentu bean może korzystać wielu klientów, programista musi zapewnić bezpieczny wątkowo dostęp do danych komponentu bean. Utworzenie komponentu bean tego typu (jak również wszystkich innych komponentów sesyjnych) jest dość proste. To jest zwykła klasa Java z adnotacją @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
Aby utworzyć komponent EJB, należy użyć adnotacji z pliku 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 MessageDrivensprawia, ż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 MessageListeneri 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 .
  1. Utwórz nowy projekt Maven w IntelliJ IDEA.

    Plik -> Nowy -> Projekt...

    Przedstawiamy EJB - 3
  2. Kliknij Następny .

  3. Wypełnij parametry projektu Maven:

    Przedstawiamy EJB - 4
  4. Kliknij Zakończ

  5. Projekt został stworzony i ma następującą strukturę:

    Przedstawiamy EJB - 5
Plik pom.xml wygląda następująco: Przedstawiamy EJB - 6W pierwszej kolejności musimy dodać zależność od API Java EE, a także określić opakowanie naszego projektu w postaci archiwum aplikacji webowej (war). W tym celu należy zmienić kod pom.xml na następującą postać:
<?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.lecturesutworzymy 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 DemoServletw 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 — @EJBwykonuje 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 - HttpServletRequesti HttpServletResponse. HttpServletRequestsłuży do uzyskania informacji o przychodzącym żądaniu HTTP. HttpServletResponsepotrzebne do wygenerowania odpowiedzi na żądanie. Wewnątrz metody pobieramy obiekt PrintWriterz 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 PrintWriterobiektu -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: Przedstawiamy EJB - 7Po 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: Przedstawiamy EJB - 8A także przeglądarkę, która się otworzy: Przedstawiamy EJB - 9Wszystko 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
Przypomnijmy, że EJB występują w następujących typach:
  • 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)
Napisaliśmy także małą aplikację HelloWorld przy użyciu EJB. Jako PD możesz samodzielnie powtórzyć praktyczną część tego artykułu. Następnie dodaj do swojej aplikacji jeszcze dwa serwlety, które do otrzymania wartości będą używać komponentów bean stanowych i pojedynczych.
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION