ในบทความนี้เราจะดูที่ EJB - Enterprise JavaBeans เทคโนโลยีนี้เป็นส่วนหนึ่งของข้อกำหนด Java EE เราจะพูดถึงประเด็นต่างๆ เช่น:
บทความนี้จะเป็นประโยชน์สำหรับผู้อ่านที่คุ้นเคยกับ Java SE และเริ่มเรียนรู้ Java EE แล้ว เพื่อให้เข้าใจส่วนที่เป็นประโยชน์ของบทความนี้อย่างถ่องแท้ ขอแนะนำให้คุณอ่านบทความ " การตั้งค่าสภาพแวดล้อมในท้องถิ่น " ก่อน
ด้านล่างนี้เราจะดูรายละเอียดเพิ่มเติมเกี่ยวกับถั่วแต่ละประเภท
ก่อนอื่น เราต้องเพิ่มการพึ่งพา Java EE API และยังระบุแพ็คเกจของโครงการของเราในรูปแบบของไฟล์เก็บถาวรแอปพลิเคชันเว็บ (war) เมื่อต้องการทำเช่นนี้ คุณต้องเปลี่ยนโค้ด pom.xml เป็นรูปแบบต่อไปนี้:
หลังจากสร้างการกำหนดค่าการเรียกใช้แล้ว ให้เปิดแอปพลิเคชันโดยใช้ เมนู Run -> Run 'ejb_demo'หรือใช้ ปุ่ม ลัดShift+F10 หลังจากเปิดตัวคุณสามารถดูบันทึก:
และเบราว์เซอร์ที่เปิดขึ้น:
ทั้งหมดนี้บ่งชี้ว่าแอปพลิเคชันทำงานตามที่ตั้งใจไว้
- EJB คืออะไร;
- ประวัติของ EJB คืออะไร;
- EJB มีกี่ประเภท?
ประวัติโดยย่อของ EJB
ย้อนกลับไปในปี 1996 เมื่อผู้เขียนบทความนี้อายุได้ 5 ขวบ Java ได้รับความนิยมในหมู่นักพัฒนาอยู่แล้ว เหตุผลก็คือ API ที่เป็นมิตร การรวบรวมขยะอัตโนมัติ ฯลฯ Java ถูกนำมาใช้กันอย่างแพร่หลายในระบบที่รับผิดชอบแบ็กเอนด์ อย่างไรก็ตาม แม้ว่าภาษาจะน่าพึงพอใจ แต่โปรแกรมเมอร์ในยุคนั้นก็ต้องการฟังก์ชันการทำงานบางอย่างที่ยังไม่ได้นำมาใช้ใน JDK ความต้องการเหล่านี้คือ:- รับประกันความคงอยู่ของข้อมูล
- ความสมบูรณ์ของธุรกรรม
- การเข้าถึงข้อมูลเชิงแข่งขัน (การควบคุมแบบมัลติเธรด);
- และน่าจะเป็นอย่างอื่น
อีเจบีคืออะไร
EJB ในแง่หนึ่งเป็นคำเรียกรวมที่อาจหมายถึงเทคโนโลยี Enterprise JavaBeans โดยทั่วไป หรือส่วนประกอบซอฟต์แวร์ Enterprise JavaBean (bean) เฉพาะบางส่วนที่เป็นส่วนหนึ่งของเทคโนโลยี EJB คำจำกัดความของ EJB ในฐานะเทคโนโลยีมีให้ในวิกิพีเดีย: Enterprise JavaBeans (หรือมักใช้เป็นตัวย่อ EJB) เป็นข้อกำหนดของเทคโนโลยีสำหรับการเขียนและสนับสนุนส่วนประกอบเซิร์ฟเวอร์ที่มีตรรกะทางธุรกิจ มันเป็นส่วนหนึ่งของ Java EE โดยทั่วไปเทคโนโลยีนี้จะใช้เมื่อตรรกะทางธุรกิจต้องการบริการต่อไปนี้อย่างน้อยหนึ่งบริการ และมักจะทั้งหมด:- รองรับการคงอยู่ของข้อมูล: ข้อมูลควรปลอดภัยแม้หลังจากหยุดโปรแกรมแล้ว ส่วนใหญ่มักจะทำได้โดยใช้ฐานข้อมูล
- รองรับการทำธุรกรรมแบบกระจาย
- รองรับการแก้ไขข้อมูลแบบขนานและมัลติเธรด
- การสนับสนุนกิจกรรม
- การสนับสนุนการตั้งชื่อและไดเร็กทอรี (JNDI);
- ความปลอดภัยและการจำกัดการเข้าถึงข้อมูล
- รองรับการติดตั้งอัตโนมัติบนแอปพลิเคชันเซิร์ฟเวอร์
- การเข้าถึงระยะไกล
ประเภทอีเจบี
มาสรุปกัน EJB เป็นคลาส Java ปกติที่ทำเครื่องหมายด้วยคำอธิบายประกอบพิเศษอย่างใดอย่างหนึ่ง คลาสดังกล่าวเรียกว่าถั่ว ขึ้นอยู่กับว่าคลาสนั้นถูกทำเครื่องหมายด้วยคำอธิบายประกอบใด คลาสนั้นจะเป็นตัวแทนของ EJB (ถั่ว) ประเภทหนึ่งหรือประเภทอื่น ถั่วมีสามประเภทหลัก:- ถั่วที่ขับเคลื่อนด้วยข้อความ (ถั่วที่ขับเคลื่อนด้วยข้อความ);
- Entity Beans - กำหนดในข้อกำหนด JPA (Java Persistence API) และใช้เพื่อจัดเก็บข้อมูล
- เซสชั่นถั่ว
- ไร้สัญชาติ (ไม่มีสถานะ);
- stateful (พร้อมรองรับสถานะเซสชันปัจจุบัน);
- singleton (หนึ่งวัตถุสำหรับแอปพลิเคชันทั้งหมด เริ่มต้นจาก EJB 3.1)

เซสชั่นถั่ว
Session Beans หรือ Session Beans เป็นถั่วประเภทหนึ่งโดยเฉพาะ พวกเขาสรุปตรรกะทางธุรกิจที่ไคลเอนต์สามารถเรียกใช้โดยทางโปรแกรมโดยการเรียกเมธอดของ bean การเรียกเมธอดสามารถทำได้:- ภายในเครื่องโดยคลาสอื่นใน JVM เดียวกันกับ session bean
- จากระยะไกล ผ่านเครือข่าย จาก JVM อื่น โดยใช้เทคโนโลยี Java RMI (Remote Method Invocation)
@Stateless
ประกอบ ลองยกตัวอย่างด้านล่าง:
import javax.ejb.Stateless;
@Stateless
public class StatelessEjbExample {
public String sayHi() {
return "Hi, I'm Stateless EJB!";
}
}
Session bean ที่รองรับสถานะเซสชันปัจจุบัน (Stateful)จะเก็บข้อมูลเกี่ยวกับสถานะระหว่างการเรียกจากไคลเอนต์เดียวกันและยุติการดำรงอยู่เมื่อมีการร้องขออย่างชัดเจนจากไคลเอนต์ สิ่งนี้เกิดขึ้นได้เนื่องจาก stateful bean นั้นมีเอกลักษณ์เฉพาะตัวสำหรับลูกค้าแต่ละราย ตัวอย่างของงานที่ bean ประเภทนี้รับผิดชอบได้คือทำให้ตะกร้าสินค้าในร้านค้าออนไลน์เป็นปัจจุบันสำหรับผู้ใช้แต่ละคน วงจรชีวิตของถั่วเหล่านี้ได้รับการจัดการโดยคอนเทนเนอร์ EJB ถั่วเหล่านี้จะถูกทำลายเช่นกันเมื่อไคลเอนต์ออก ถั่วดังกล่าวก็สร้างได้ง่ายเช่นกัน นี่คือคลาส Java ที่ทำเครื่องหมายด้วยคำอธิบายStateful
ประกอบ ตัวอย่างด้านล่าง:
import javax.ejb.Stateful;
@Stateful
public class StatefulEjbExample {
public String sayHi() {
return "Hi, I,m Stateful EJB";
}
}
Singleton session beanจะเริ่มทำงานหนึ่งครั้งตลอดอายุการใช้งานของแอปพลิเคชัน และมีอยู่ตลอดอายุของแอปพลิเคชัน bean ดังกล่าวได้รับการออกแบบมาสำหรับสถานการณ์ที่ต้องแชร์สถานะหนึ่งกับไคลเอนต์ทั้งหมด เช่นเดียวกับ stateless bean ใน bean แบบสแตนด์อโลน นักพัฒนาจำเป็นต้องตรวจสอบให้แน่ใจว่าสภาพแวดล้อมภายใน bean ได้รับการจัดระเบียบในลักษณะที่ปลอดภัยต่อเธรด เรามายกตัวอย่าง Singleton bean ซึ่งสร้างได้ง่ายพอๆ กับถั่วชนิดเดียวกันดังที่กล่าวไว้ข้างต้น เป็นเรื่องง่ายที่จะเดาว่านี่คือคลาส Java ที่มีคำอธิบาย@Singleton
ประกอบ อย่างไรก็ตามในกรณีนี้คุณต้องระมัดระวัง มีคำอธิบายประกอบสองรายการ ในรูปแบบไวยากรณ์เหมือนกัน แต่มีวัตถุประสงค์ต่างกันและอยู่ในแพ็กเกจต่างกัน:
- javax.ejb.ซิงเกิลตัน
- javax.inject.ซิงเกิลตัน
javax.ejb
. ตัวอย่างด้านล่าง:
import javax.ejb.Singleton;
@Singleton
public class SingletonEjbExample {
public String sayHi() {
return "Hi, I'm Singleton EJB!";
}
}
ข้อความขับเคลื่อนถั่ว
Message Driven Beans หรือ MDB หรือ bean ที่ขับเคลื่อนด้วยข้อความ ใช้ตรรกะทางธุรกิจบางอย่าง เช่น session bean แต่ MDB มีความแตกต่างที่สำคัญอย่างหนึ่งไม่เหมือนกับญาติของมัน ลูกค้าไม่เคยเรียกวิธี MDB โดยตรง bean ดังกล่าวส่วนใหญ่มักทำหน้าที่เป็นผู้ฟังข้อความ JMS (Java Message Service) และทำหน้าที่จัดระเบียบการแลกเปลี่ยนข้อความแบบอะซิงโครนัสระหว่างส่วนต่างๆ ของระบบ ตัวอย่างของข้อความดังกล่าวคือการร้องขอให้จัดส่งสินค้าคงคลังจากระบบขายปลีกอัตโนมัติไปยังระบบการจัดการอุปทาน ด้านล่างนี้เป็นตัวอย่างของ MDB bean แตกต่างจาก session 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
ประกอบ
ถั่วเอนทิตี
ส่วนหนึ่งของเทคโนโลยี EJB คือข้อกำหนด JPA JPA หรือ Java Persistence API เป็นข้อกำหนดที่ให้ Object-Relational Mapping (ORM) ของอ็อบเจ็กต์ Java (Entity bean) และจัดเตรียม API สำหรับจัดเก็บ ดึงข้อมูล และจัดการอ็อบเจ็กต์ดังกล่าว JPA อนุญาตให้คุณแสดงข้อมูลจากฐานข้อมูลเป็นอ็อบเจ็กต์ Java รวมถึงบันทึกอ็อบเจ็กต์ Java เป็นบันทึกในฐานข้อมูล ไม่ใช่ทุกคลาสที่สามารถทำหน้าที่เป็นวัตถุดังกล่าวได้ แต่ Entity bean Entity Bean เป็นคลาส Java ที่แสดงถึงตารางในฐานข้อมูล การแสดงผล (การแมป) ทำได้โดยการใช้คำอธิบายประกอบพิเศษ ด้วยความช่วยเหลือของพวกเขา คลาส Java จะถูกเปรียบเทียบกับตารางในฐานข้อมูล เช่นเดียวกับการเปรียบเทียบฟิลด์ของคลาส Java กับฟิลด์ของตารางฐานข้อมูล นี่คือตัวอย่างของ Entity 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...
}
เป็นที่น่าสังเกตว่าถั่วประเภทนี้เหมาะสมที่จะศึกษาเฉพาะในบริบทของการศึกษาข้อกำหนด JPA เท่านั้น
การเขียนใบสมัคร: EJB HelloWorld
ในส่วนนี้ เราจะเขียนแอปพลิเคชัน Java EE HelloWorld ขนาดเล็ก ซึ่งเราจะปรับใช้บนเซิร์ฟเวอร์ GlassFish ก่อนที่จะอ่านบทความนี้ ขอแนะนำอย่างยิ่งให้คุณอ่านบทความเกี่ยวกับการตั้งค่าสภาพแวดล้อมในเครื่องของคุณ-
สร้างโปรเจ็กต์ Maven ใหม่ใน IntelliJ IDEA
ไฟล์ -> ใหม่ -> โครงการ...
-
คลิกถัดไป
-
กรอกพารามิเตอร์โครงการ 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 เซิร์ฟเล็ตและ 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!";
}
}
ดังที่กล่าวไว้ก่อนหน้านี้ทุกอย่างค่อนข้างง่าย ขั้นตอนต่อไปของเราคือการสร้างเซิร์ฟเล็ตที่จะส่งค่าจาก EJB เป็นการตอบสนองต่อคำขอ HTTP เป็นที่น่าสังเกตว่าเซิร์ฟเล็ตไม่ใช่หัวข้อของบทความนี้ แต่คุณยังคงต้องใช้เซิร์ฟเล็ตเหล่านี้เพื่อสาธิต EJB เมื่อต้องการทำเช่นนี้ เรามาสร้างเซิร์ฟเล็ตใหม่DemoServlet
ในแพ็คเกจเดียวกันกับ EJB รหัสของมันอยู่ด้านล่าง:
@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());
}
}
นี่คือความคิดเห็นสั้น ๆ เกี่ยวกับโค้ด บทคัดย่อ@WebServlet("/helloWorld")
- กำหนดคลาสของเราเป็นเซิร์ฟเล็ตที่จะประมวลผลคำขอ HTTP ไปยังจุด/helloWorld
สิ้นสุด ชั้นเรียนของเรามีหนึ่งสาขา - DemoEJB ejb
. นี่คือ bean ของเราที่กำหนดไว้ก่อนหน้านี้ คำอธิบายประกอบบนฟิลด์คลาส— @EJB
ดำเนินการฉีดการพึ่งพา (DI) เหล่านั้น. ตัวแปร ejb จะเริ่มต้นโดยอัตโนมัติด้วยอินสแตนซ์ใหม่เมื่อจำเป็น คลาสของเราเป็นทายาทของ HttpServlet และแทนที่หนึ่งในเมธอดซูเปอร์คลาสdoGet
- เมธอดนี้ประมวลผลคำขอ HTTP GET และรับพารามิเตอร์สองตัว - HttpServletRequest
และHttpServletResponse
. HttpServletRequest
ทำหน้าที่รับข้อมูลเกี่ยวกับคำขอ HTTP ที่เข้ามา HttpServletResponse
จำเป็นในการสร้างการตอบสนองต่อคำขอ ภายในเมธอด เราได้รับอ็อบเจ็กต์PrintWriter
จากอ็อบเจ็กต์ตอบสนอง ( HttpServletResponse
) โดยใช้ฟังก์ชันgetWriter()
. ต่อไป เราสามารถเขียนค่าบางอย่างให้กับวัตถุผลลัพธ์โดยใช้นามสกุลwrite
. ซึ่งในความเป็นจริงคือสิ่งที่เราใช้โดยการเขียนPrintWriter
ค่าที่ได้รับจาก EJB ที่เรากำหนดลงในวัตถุ -a (ค่าคือสตริง “Hello World!”) ไคลเอนต์ที่ส่งคำขอ HTTP จะได้รับค่านี้เป็นการตอบสนองต่อคำขอของตน ขั้นตอนต่อไปคือการเปิดแอปพลิเคชันบนเซิร์ฟเวอร์ GlassFish Java EE ในการดำเนินการนี้ เราจะสร้างการกำหนดค่าใหม่ ตามที่อธิบายไว้ในบทความเกี่ยวกับการตั้งค่าสภาพแวดล้อมภายในเครื่อง ด้านล่างนี้คือภาพหน้าจอของการกำหนดค่าที่เสร็จสิ้นแล้วสำหรับโปรเจ็กต์ปัจจุบัน ตรวจสอบให้แน่ใจว่าคุณได้ติดตั้งเซิร์ฟเวอร์ GlassFish ก่อนเริ่มต้น: 


บทสรุป
ในบทความนี้ เราได้ทำความคุ้นเคยกับ EJB - Enterprise JavaBeans เราพิจารณาคำถามเช่น:- EJB คืออะไร?
- ประวัติศาสตร์อีเจบี
- EJB ประเภทต่างๆ
- ถั่วที่ขับเคลื่อนด้วยข้อความ (ถั่วที่ขับเคลื่อนด้วยข้อความ);
- Entity Beans - กำหนดไว้ในข้อกำหนดเอนทิตี JPA (Java Persistence API) และใช้ในการจัดเก็บข้อมูล
- เซสชันถั่ว:
- ไร้สัญชาติ (ไม่มีรัฐ)
- stateful (พร้อมรองรับสถานะเซสชันปัจจุบัน)
- singleton (หนึ่งวัตถุสำหรับแอปพลิเคชันทั้งหมด เริ่มต้นจาก EJB 3.1)
GO TO FULL VERSION