在本文中,我們將了解 EJB——Enterprise JavaBeans。該技術是 Java EE 規範的一部分。我們將討論以下問題:
- 什麼是 EJB;
- EJB 的歷史是什麼?
- 有哪些類型的 EJB?
EJB 簡史
早在 1996 年,當本文作者 5 歲的時候,Java 就已經在開發者中流行起來。原因是友善的API、自動垃圾收集等。Java被廣泛應用於負責後端的系統。然而,儘管語言有很多樂趣,但當時的程式設計師需要 JDK 中尚未實現的某些功能。這些需求是:- 確保資料持久性;
- 交易完整性
- 競爭性存取資料(多執行緒控制);
- 很可能還有別的東西。
什麼是EJB
從某種意義上說,EJB 是一個集體術語,根據上下文,它可以表示一般的 Enterprise JavaBeans 技術本身,也可以表示屬於 EJB 技術一部分的某些特定 Enterprise JavaBean 軟體元件 (bean)。維基百科上給出了 EJB 作為一種技術的定義:Enterprise JavaBeans(也經常用作縮寫 EJB)是一種用於編寫和支援包含業務邏輯的伺服器元件的技術規格。它是 Java EE 的一部分。當業務邏輯至少需要以下服務之一(通常是所有服務)時,通常會使用此技術:- 支援資料持久性:即使停止程序後資料也應該是安全的。最常使用資料庫來實作;
- 支援分散式事務;
- 支援並行資料修改和多執行緒;
- 活動支援;
- 命名和目錄支援(JNDI);
- 資料存取的安全性和限制;
- 支援在應用程式伺服器上自動安裝;
- 遠端存取。
EJB類型
我們來總結一下。EJB 是一個帶有特殊註解之一的常規 Java 類別。這樣的類別稱為 Bean。根據類別標記的註釋,它將代表一種或另一種類型的 EJB(bean)。豆子主要分為三種:- Message Driven Beans(訊息驅動bean);
- Entity Beans-在JPA(Java Persistence API)規格中定義,用於儲存資料;
- 會話 Bean。
- 無狀態(無狀態);
- 有狀態(支援目前會話狀態);
- 單例(整個應用程式的一個物件;從 EJB 3.1 開始)。
會話Bean
會話 Bean,或稱為會話 Bean,是一種特定類型的 Bean。它們封裝了客戶端可以透過呼叫 bean 的方法以程式設計方式呼叫的業務邏輯。方法呼叫可以執行以下操作:- 本地,透過與會話 bean 相同的 JVM 中的另一個類別;
- 使用 Java RMI(遠端方法呼叫)技術,透過網路從另一個 JVM 進行遠端操作。
@Stateless
。下面我們舉個例子:
import javax.ejb.Stateless;
@Stateless
public class StatelessEjbExample {
public String sayHi() {
return "Hi, I'm Stateless EJB!";
}
}
支援當前會話狀態(有狀態)的會話 bean保留有關同一客戶端呼叫之間的狀態信息,並根據客戶端的明確請求終止其存在。這是因為有狀態 Bean 對於每個客戶端來說都是唯一的。這種類型的 Bean 可以負責的任務的一個範例是讓線上商店中的購物車為每個使用者保持最新。這些bean 的生命週期由EJB 容器管理。當客戶端退出時,這些 Bean 也會被銷毀。這樣的豆子也很容易創建。這是一個用註解標記的 Java 類別Stateful
。下面的例子:
import javax.ejb.Stateful;
@Stateful
public class StatefulEjbExample {
public String sayHi() {
return "Hi, I,m Stateful EJB";
}
}
單例會話 bean在應用程式的生命週期內啟動一次,並在應用程式的整個生命週期中存在。此類 Bean 專為必須在所有用戶端之間共用一種狀態的情況而設計。與無狀態 Bean 一樣,在獨立 Bean 中,開發人員需要確保 Bean 內的環境以線程安全的方式組織。讓我們舉一個 Singleton bean 的例子,它和上面討論的對應的 bean 一樣容易建立。很容易猜到這是一個帶有註解的Java類別@Singleton
。但是,在這種情況下您需要小心。有兩個註釋,語法相同,但用途不同並且位於不同的包中:
- javax.ejb.Singleton
- javax.inject.Singleton
javax.ejb
. 下面的例子:
import javax.ejb.Singleton;
@Singleton
public class SingletonEjbExample {
public String sayHi() {
return "Hi, I'm Singleton EJB!";
}
}
訊息驅動 Bean
訊息驅動 Bean(或 MDB)或訊息驅動 Bean 實現一些業務邏輯,如會話 Bean。但與它的親戚不同的是,MDB 有一個重要的區別。客戶端從不直接呼叫 MDB 方法。此類 Bean 通常充當 JMS(Java 訊息服務)訊息的偵聽器,並用於組織系統各部分之間的非同步訊息交換。此類訊息的一個範例是從自動化零售系統向供應管理系統傳送庫存的請求。下面是 MDB bean 的範例。與會話 bean 不同,它的創建更有趣一些: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();
}
}
}
該註解MessageDriven
使我們的 MDB 類別成為一個 bean。在註釋內部,使用 JNDI(在此處閱讀有關 JNDI的資訊)確定了 JMS 發行版的名稱,我們的類別將成為該發行版的偵聽器。此外,我們的類別也實作了該介面MessageListener
及其方法onMessage
。當一些訊息從佇列/分發到達且其名稱在註解中定義時,將呼叫此方法MessageDriven
。
實體bean
EJB 技術的一部分是 JPA 規格。JPA(即 Java Persistence API)是一種規範,它提供 Java 物件(實體 bean)的物件關係映射 (ORM),並提供用於儲存、檢索和管理此類物件的 API。JPA 允許您將資料庫中的資料表示為 Java 對象,以及將 Java 對象保存為資料庫中的記錄。並不是每個類別都可以充當這樣的對象,但實體 bean 除外。Entity Bean 是一個 Java 類,表示資料庫中的表。顯示(映射)是透過使用特殊註釋來實現的。在它們的幫助下,可以將 Java 類別與資料庫中的表格進行比較,以及將 Java 類別的欄位與資料庫表格的欄位進行比較。下面是一個實體 bean 的範例,程式碼中帶有註解:@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...
}
值得注意的是,這種類型的 bean 僅在研究 JPA 規範的背景下才有意義。
編寫應用程式:EJB HelloWorld
在本節中,我們將編寫一個小型 Java EE HelloWorld 應用程序,並將其部署在 GlassFish 伺服器上。在閱讀本文之前,強烈建議您閱讀有關設定本地環境的文章。-
在 IntelliJ IDEA 中建立一個新的 Maven 專案。
文件 -> 新建 -> 項目...
-
點擊下一步。
-
填寫Maven項目參數:
-
按一下“完成”
-
該專案已建立並具有以下結構:
<?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>
接下來,您可以繼續處理 Java 程式碼。我們的應用程式將是最簡單的。我們將有 1 個 servlet 和 1 個 EJB。這將是一個無狀態會話 bean。在 EJB 內部,我們將只定義 1 個傳回字串「Hello World」的方法。首先,讓我們創建一個套件com.javarush.lectures
。然後,在包內com.javarush.lectures
,我們將建立我們的 bean - DemoEJB。bean程式碼如下:
import javax.ejb.Stateless;
@Stateless
public class DemoEJB {
public String helloWorld() {
return "Hello world!";
}
}
正如前面所說,一切都很簡單。我們的下一步是建立一個 servlet,它將傳遞來自 EJB 的值作為對 HTTP 請求的回應。值得注意的是,servlet 不是本文的主題,但您仍然需要使用它們來示範 EJB。為此,我們DemoServlet
在與 EJB 相同的套件中建立一個新的 servlet。其程式碼如下:
@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());
}
}
以下是對程式碼的一些簡短評論。Abstract @WebServlet("/helloWorld")
- 將我們的類別定義為 servlet,它將處理對端點的 HTTP 請求/helloWorld
。我們班有一個場地—— DemoEJB ejb
. 這是我們之前定義的 bean。類別欄位上的註解 —@EJB
執行依賴項注入 (DI)。那些。需要時,ejb 變數會自動以新實例進行初始化。我們的類別是 HttpServlet 的後代,並重寫超類別方法之一 - doGet
。此方法處理 HTTP GET 請求並採用兩個參數 -HttpServletRequest
和HttpServletResponse
。HttpServletRequest
用於取得有關傳入 HTTP 請求的資訊。HttpServletResponse
需要產生對請求的回應。在方法內部,我們使用PrintWriter
.response 物件從回應物件 ( ) 取得物件。接下來,我們可以使用 向結果物件寫入一些值。事實上,我們透過將從我們定義的 EJB 獲得的值寫入 -a 物件來使用它(該值是字串「Hello World!」)。發送 HTTP 請求的用戶端將收到此值作為對其請求的回應。下一步是在 GlassFish Java EE 伺服器上啟動應用程式。為此,我們將建立一個新配置,如有關設定本地環境的文章所述。下面是目前專案完成配置的螢幕截圖。確保在開始之前安裝了 GlassFish 伺服器: 建立啟動配置後,使用Run -> Run 'ejb_demo'選單或使用Shift+F10熱鍵啟動應用程式。啟動後,您可以看到它的日誌: 以及打開的瀏覽器: 所有這些都表明應用程式按預期工作。 HttpServletResponse
getWriter()
write
PrintWriter
結論
在本文中,我們了解了 EJB——Enterprise JavaBeans。我們考慮了以下問題:- 什麼是EJB?
- EJB歷史
- 不同類型的 EJB
- Message Driven Beans(訊息驅動bean);
- Entity Beans - 在JPA(Java Persistence API)實體規格中定義並用於儲存資料;
- 會話 Bean:
- 無狀態(無狀態)
- 有狀態(支援目前會話狀態)
- 單例(整個應用程式的一個物件;從 EJB 3.1 開始)
GO TO FULL VERSION