JavaRush /Blog Java /Random-VI /Giới thiệu EJB
Анзор Кармов
Mức độ
Санкт-Петербург

Giới thiệu EJB

Xuất bản trong nhóm
Trong bài viết này chúng ta sẽ xem xét EJB - Enterprise JavaBeans. Công nghệ này là một phần của đặc tả Java EE. Chúng tôi sẽ đề cập đến các vấn đề như:
  • EJB là gì;
  • lịch sử của EJB là gì;
  • có những loại EJB nào?
Chúng ta cũng sẽ viết một ứng dụng HelloWorld nhỏ sử dụng EJB và servlet. Giới thiệu EJB - 1Bài viết này sẽ hữu ích cho những độc giả đã quen với Java SE và đang bắt đầu học Java EE. Để hiểu đầy đủ phần thực tế của bài viết này, trước tiên bạn nên đọc bài viết “ Thiết lập môi trường cục bộ ”.

Tóm tắt lịch sử của EJB

Trở lại năm 1996, khi tác giả của bài viết này mới 5 tuổi, Java đã được các nhà phát triển ưa chuộng. Lý do cho điều này là API thân thiện, thu thập rác tự động, v.v. Java được sử dụng rộng rãi trong các hệ thống chịu trách nhiệm về phần phụ trợ. Tuy nhiên, bất chấp tất cả những điều thú vị của ngôn ngữ này, các lập trình viên thời đó vẫn cần một số chức năng nhất định chưa được triển khai trong JDK. Những nhu cầu này là:
  • đảm bảo tính bền vững của dữ liệu;
  • tính toàn vẹn của giao dịch
  • truy cập dữ liệu cạnh tranh (điều khiển đa luồng);
  • và rất có thể là cái gì đó khác.
Tất cả điều này đã dẫn đến sự gia tăng tự nhiên về số lượng các thư viện đóng cửa, tự viết, tự viết tại nhà. Nói cách khác, mọi người đều đáp ứng nhu cầu của mình một cách tốt nhất có thể. Đó là cho đến khi IBM đưa ra khẩu hiệu “Mọi người nên đáp ứng nhu cầu của mình theo cùng một cách” và phát hành đặc tả Enterprise Java Bean (EJB) vào năm 1997. Chính điều này đã giúp có thể thống nhất quá trình phát triển và đưa giải pháp cho các vấn đề điển hình (được mô tả ở trên là nhu cầu) vào khuôn khổ. Sun đã điều chỉnh đứa con tinh thần của IBM trong 2 năm và vào năm 1999 đã phát hành đặc tả EJB 1.0. Đây là cách công nghệ ra đời, điều này sẽ được thảo luận thêm ở khía cạnh ứng dụng nhiều hơn.

EJB là gì

Theo một nghĩa nào đó, EJB là một thuật ngữ chung, tùy thuộc vào ngữ cảnh, có thể có nghĩa là bản thân công nghệ Enterprise JavaBeans nói chung hoặc một số thành phần phần mềm Enterprise JavaBean cụ thể (bean) là một phần của công nghệ EJB. Định nghĩa EJB như một công nghệ được đưa ra trên Wikipedia: Enterprise JavaBeans (cũng thường được sử dụng như một từ viết tắt EJB) là một đặc tả của một công nghệ để viết và hỗ trợ các thành phần máy chủ chứa logic nghiệp vụ. Nó là một phần của Java EE. Công nghệ này thường được sử dụng khi logic nghiệp vụ yêu cầu ít nhất một trong các dịch vụ sau và thường là tất cả các dịch vụ đó:
  • hỗ trợ duy trì dữ liệu: dữ liệu phải được an toàn ngay cả sau khi dừng chương trình. Thường đạt được nhất bằng cách sử dụng cơ sở dữ liệu;
  • hỗ trợ các giao dịch phân tán;
  • hỗ trợ sửa đổi dữ liệu song song và đa luồng;
  • hỗ trợ sự kiện;
  • hỗ trợ đặt tên và thư mục (JNDI);
  • bảo mật và hạn chế quyền truy cập vào dữ liệu;
  • hỗ trợ cài đặt tự động trên máy chủ ứng dụng;
  • Truy cập từ xa.
Các dịch vụ được liệt kê ở trên là một lợi thế chắc chắn của công nghệ EJB. Một ưu điểm khác là mọi thứ được liệt kê ở trên đều hoạt động ngay lập tức. Những thứ kia. lập trình viên không cần phải suy nghĩ đến việc hỗ trợ các giao dịch phân tán. Lập trình viên chỉ cần nghĩ về logic nghiệp vụ mà anh ta hiện đang cố gắng thực hiện. EJB với tư cách là một thành phần phần mềm cụ thể là một lớp Java có một hoặc nhiều chú thích từ đặc tả EJB chứa một số logic nghiệp vụ của ứng dụng. Các chú thích từ đặc tả EJB cung cấp cho lớp được gắn thẻ một số quyền hạn, quyền hạn và siêu năng lực nhất định. Đọc thêm về điều này dưới đây.

các loại EJB

Hãy tóm tắt. EJB là một lớp Java thông thường được đánh dấu bằng một trong các chú thích đặc biệt. Những lớp như vậy được gọi là đậu. Tùy thuộc vào chú thích mà lớp được đánh dấu, nó sẽ là đại diện của một hoặc một loại EJB (đậu) khác. Có ba loại đậu chính:
  • Message Driven Beans (đậu điều khiển thông điệp);
  • Đậu thực thể - được xác định trong đặc tả JPA (Java Persistence API) và được sử dụng để lưu trữ dữ liệu;
  • Đậu phiên.
Loại thứ hai (đậu phiên) được chia thành nhiều loại phụ:
  • không quốc tịch (không có nhà nước);
  • trạng thái (có hỗ trợ cho trạng thái phiên hiện tại);
  • singleton (một đối tượng cho toàn bộ ứng dụng; bắt đầu từ EJB 3.1).
Giới thiệu EJB - 2Dưới đây chúng ta sẽ xem xét từng loại đậu chi tiết hơn.

Đậu phiên

Đậu phiên, hay đậu phiên, là một loại đậu cụ thể. Chúng đóng gói logic nghiệp vụ mà máy khách có thể gọi theo chương trình bằng cách gọi các phương thức của Bean. Một cuộc gọi phương thức có thể thực hiện:
  • cục bộ, bởi một lớp khác trong cùng một JVM với phiên Bean;
  • từ xa, qua mạng, từ một JVM khác, sử dụng công nghệ Java RMI (Gọi phương thức từ xa).
Từ “session” ngụ ý rằng Bean chỉ khả dụng khi máy chủ đang thực hiện một tác vụ cụ thể và bị phá hủy không thể khắc phục được trong trường hợp máy chủ bị lỗi hoặc tắt máy. Vòng đời của một cá thể session Bean được điều khiển bởi một bộ chứa EJB (bạn có thể đọc thêm về các bộ chứa EJB trong bài giảng đầu tiên của loạt bài này ). Đậu phiên không trạng thái không lưu trữ thông tin về trạng thái của chúng. Loại thành phần này có thể được sử dụng bởi nhiều khách hàng khác nhau. Đậu không trạng thái được sử dụng để thực hiện các quy trình kinh doanh có thể được hoàn thành trong một hoạt động. Ví dụ: kiểm tra lịch sử tín dụng của khách hàng. Bởi vì một phiên bản Bean có thể được nhiều khách hàng sử dụng nên nhà phát triển phải cung cấp quyền truy cập an toàn theo luồng vào dữ liệu của Bean. Việc tạo một Bean kiểu này (cũng như tất cả các Session Bean khác) khá đơn giản. Đây là một lớp Java thông thường có chú thích @Stateless. Hãy đưa ra một ví dụ dưới đây:
import javax.ejb.Stateless;

@Stateless
public class StatelessEjbExample {
    public String sayHi() {
        return "Hi, I'm Stateless EJB!";
    }
}
Đậu phiên hỗ trợ trạng thái phiên hiện tại (Trạng thái) lưu giữ thông tin về trạng thái của chúng giữa các cuộc gọi đến nó từ cùng một khách hàng và chấm dứt sự tồn tại của chúng theo yêu cầu rõ ràng từ khách hàng. Điều này đạt được là do các stateful Bean là duy nhất cho mỗi client. Một ví dụ về nhiệm vụ mà loại đậu này có thể chịu trách nhiệm là cập nhật giỏ hàng trong cửa hàng trực tuyến cho mỗi người dùng. Vòng đời của những hạt đậu này được quản lý bởi vùng chứa EJB. Những hạt đậu này cũng bị phá hủy khi khách hàng thoát ra. Những loại đậu như vậy cũng khá dễ tạo ra. Đây là lớp Java được đánh dấu bằng chú thích Stateful. Ví dụ dưới đây:
import javax.ejb.Stateful;

@Stateful
public class StatefulEjbExample {
    public String sayHi() {
        return "Hi, I,m Stateful EJB";
    }
}
Đậu phiên Singleton được khởi tạo một lần trong suốt vòng đời của ứng dụng và tồn tại trong suốt vòng đời của ứng dụng. Những loại đậu như vậy được thiết kế cho các tình huống trong đó một trạng thái phải được chia sẻ giữa tất cả các máy khách. Giống như các loại đậu không trạng thái, trong các loại đậu độc lập, nhà phát triển cần đảm bảo rằng môi trường bên trong đậu được tổ chức theo cách an toàn theo luồng. Hãy đưa ra một ví dụ về đậu Singleton, loại đậu này dễ tạo như các đối tác của nó, đã được thảo luận ở trên. Dễ dàng đoán được đây là một lớp Java có chú thích @Singleton. Tuy nhiên, trong trường hợp này bạn cần phải cẩn thận. Có hai chú thích, giống nhau về cú pháp, nhưng khác nhau về mục đích và nằm trong các gói khác nhau:
  • javax.ejb.Singleton
  • javax.inject.Singleton
Để tạo EJB, bạn phải sử dụng chú thích từ tệp javax.ejb. Ví dụ dưới đây:
import javax.ejb.Singleton;

@Singleton
public class SingletonEjbExample {
    public String sayHi() {
        return "Hi, I'm Singleton EJB!";
    }
}

Đậu điều khiển bằng tin nhắn

Đậu điều khiển thông báo, hay MDB, hoặc đậu điều khiển thông báo, triển khai một số logic nghiệp vụ, như đậu phiên. Nhưng không giống như những người thân của nó, MDB có một điểm khác biệt quan trọng. Khách hàng không bao giờ gọi trực tiếp các phương thức MDB. Những hạt đậu như vậy thường đóng vai trò là người nghe các tin nhắn JMS (Dịch vụ tin nhắn Java) và dùng để tổ chức trao đổi tin nhắn không đồng bộ giữa các bộ phận của hệ thống. Ví dụ về thông báo như vậy là yêu cầu phân phối hàng tồn kho từ hệ thống bán lẻ tự động đến hệ thống quản lý cung ứng. Dưới đây là một ví dụ về đậu MDB. Không giống như session Bean, việc tạo ra nó thú vị hơn một chút:
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();
        }
    }

}
Chú thích MessageDrivenlàm cho lớp MDB của chúng ta trở thành một hạt đậu. Bên trong chú thích, sử dụng JNDI (đọc về JNDI tại đây ), tên của bản phân phối JMS được xác định mà lớp của chúng ta sẽ trở thành người nghe. Ngoài ra, lớp của chúng tôi thực hiện giao diện MessageListenervà phương thức của nó onMessage. Phương thức này sẽ được gọi khi một số tin nhắn đến từ hàng đợi/phân phối với tên được xác định bên trong chú thích MessageDriven.

Đậu thực thể

Một phần của công nghệ EJB là đặc tả JPA. JPA, hay Java Persistence API, là một đặc tả cung cấp Ánh xạ quan hệ đối tượng (ORM) của các đối tượng Java (Các hạt thực thể) và cung cấp API để lưu trữ, truy xuất và quản lý các đối tượng đó. JPA cho phép bạn biểu diễn dữ liệu từ cơ sở dữ liệu dưới dạng các đối tượng Java, cũng như lưu các đối tượng Java dưới dạng bản ghi trong cơ sở dữ liệu. Không phải mọi lớp đều có thể hoạt động như một đối tượng như vậy, ngoại trừ các hạt Thực thể. Entity Bean là một lớp Java đại diện cho một bảng trong cơ sở dữ liệu. Hiển thị (ánh xạ) đạt được thông qua việc sử dụng các chú thích đặc biệt. Với sự trợ giúp của họ, một lớp Java được so sánh với một bảng trong cơ sở dữ liệu, cũng như các trường của lớp Java được so sánh với các trường của bảng cơ sở dữ liệu. Đây là một ví dụ về Bean Entity, với các nhận xét trong mã:
@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...
}
Điều đáng chú ý là loại đậu này chỉ có ý nghĩa khi nghiên cứu trong bối cảnh nghiên cứu đặc tả JPA.

Viết đơn đăng ký: EJB HelloWorld

Trong phần này, chúng tôi sẽ viết một ứng dụng Java EE HelloWorld nhỏ mà chúng tôi sẽ triển khai trên máy chủ GlassFish. Trước khi đọc bài viết này, bạn nên đọc bài viết về thiết lập môi trường cục bộ của mình .
  1. Tạo một dự án Maven mới trong IntelliJ IDEA.

    Tệp -> Mới -> Dự án...

    Giới thiệu EJB - 3
  2. Bấm tiếp .

  3. Điền thông số dự án Maven:

    Giới thiệu EJB - 4
  4. Nhấp vào Hoàn tất

  5. Project đã được tạo và có cấu trúc như sau:

    Giới thiệu EJB - 5
Tệp pom.xml trông như thế này: Giới thiệu EJB - 6Trước hết, chúng ta cần thêm một phần phụ thuộc vào API Java EE, đồng thời chỉ định việc đóng gói dự án của chúng ta dưới dạng kho lưu trữ ứng dụng web (chiến tranh). Để thực hiện việc này, bạn cần thay đổi mã pom.xml thành dạng sau:
<?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>
Tiếp theo, bạn có thể chuyển sang mã Java. Ứng dụng của chúng tôi sẽ đơn giản nhất. Chúng ta sẽ có 1 servlet và 1 EJB. Đây sẽ là một phiên đậu không trạng thái. Bên trong EJB chúng ta sẽ chỉ định nghĩa 1 phương thức trả về chuỗi “Hello World”. Trước hết, hãy tạo một gói com.javarush.lectures. Sau đó, bên trong gói com.javarush.lectures, chúng ta sẽ tạo Bean - DemoEJB. Mã đậu được đưa ra dưới đây:
import javax.ejb.Stateless;

@Stateless
public class DemoEJB {
    public String helloWorld() {
        return "Hello world!";
    }
}
Như đã nói trước đó, mọi thứ khá đơn giản. Bước tiếp theo của chúng ta là tạo một servlet sẽ chuyển giá trị từ EJB dưới dạng phản hồi cho yêu cầu HTTP. Cần lưu ý rằng các servlet không phải là chủ đề của bài viết này, nhưng bạn vẫn cần sử dụng chúng để chứng minh EJB. Để làm điều này, hãy tạo một servlet mới DemoServlettrong cùng gói với EJB. Mã của nó là dưới đây:
@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());
    }
}
Dưới đây là một số nhận xét ngắn về mã. Tóm tắt @WebServlet("/helloWorld")- định nghĩa lớp của chúng ta là một servlet sẽ xử lý các yêu cầu HTTP đến điểm cuối /helloWorld. Lớp của chúng tôi có một trường - DemoEJB ejb. Đây là đậu của chúng tôi được xác định trước đó. Chú thích trên trường lớp— @EJBthực hiện chèn phụ thuộc (DI). Những thứ kia. Biến ejb được tự động khởi tạo với một phiên bản mới khi được yêu cầu. Lớp của chúng tôi là hậu duệ của HttpServlet và ghi đè một trong các phương thức siêu lớp - doGet. Phương thức này xử lý các yêu cầu HTTP GET và nhận hai tham số - HttpServletRequestHttpServletResponse. HttpServletRequestdùng để lấy thông tin về yêu cầu HTTP đến. HttpServletResponsecần thiết để tạo ra phản hồi cho một yêu cầu. Bên trong phương thức, chúng ta lấy đối tượng PrintWritertừ đối tượng phản hồi ( HttpServletResponse), sử dụng getWriter(). Tiếp theo, chúng ta có thể ghi một số giá trị vào đối tượng kết quả bằng cách sử dụng write. Trên thực tế, đó là những gì chúng ta sử dụng bằng cách ghi vào PrintWriterđối tượng -a giá trị thu được từ EJB mà chúng ta đã xác định (giá trị là chuỗi “Hello World!”). Máy khách đã gửi yêu cầu HTTP sẽ nhận được giá trị này dưới dạng phản hồi cho yêu cầu của nó. Bước tiếp theo là khởi chạy ứng dụng trên máy chủ GlassFish Java EE. Để thực hiện việc này, chúng ta sẽ tạo một cấu hình mới, như được mô tả trong bài viết về thiết lập môi trường cục bộ . Dưới đây là ảnh chụp màn hình cấu hình đã hoàn thành cho dự án hiện tại. Đảm bảo rằng bạn đã cài đặt máy chủ GlassFish trước khi bắt đầu: Giới thiệu EJB - 7Sau khi tạo cấu hình khởi chạy, hãy khởi chạy ứng dụng bằng menu Run -> Run 'ejb_demo' hoặc sử dụng phím nóng Shift+F10 . Sau khi khởi chạy, bạn có thể xem nhật ký của nó: Giới thiệu EJB - 8Và cả trình duyệt mở ra: Giới thiệu EJB - 9Tất cả điều này cho thấy ứng dụng hoạt động như dự định.

Phần kết luận

Trong bài viết này chúng ta đã làm quen với EJB - Enterprise JavaBeans. Chúng tôi đã xem xét các câu hỏi như:
  • EJB là gì?
  • Lịch sử EJB
  • Các loại EJB khác nhau
Hãy nhớ lại rằng EJB có các loại sau:
  • Message Driven Beans (đậu điều khiển thông điệp);
  • Đậu thực thể - được xác định trong đặc tả thực thể JPA (Java Persistence API) và được sử dụng để lưu trữ dữ liệu;
  • Đậu phiên:
    • không quốc tịch (không có trạng thái)
    • trạng thái (có hỗ trợ cho trạng thái phiên hiện tại)
    • singleton (một đối tượng cho toàn bộ ứng dụng; bắt đầu từ EJB 3.1)
Chúng tôi cũng đã viết một ứng dụng HelloWorld nhỏ bằng EJB. Với tư cách là một PD, bạn có thể tự mình lặp lại phần thực tế của bài viết này. Và sau đó thêm hai servlet nữa vào ứng dụng của bạn sẽ sử dụng các stateful và singleton để nhận giá trị.
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION