Анзор Кармов
مستوى
Санкт-Петербург

تقديم EJB

نشرت في المجموعة
في هذه المقالة سنلقي نظرة على EJB - Enterprise JavaBeans. تعد هذه التقنية جزءًا من مواصفات Java EE. وسوف نتطرق إلى قضايا مثل:
  • ما هو EJB؟
  • ما هو تاريخ EJB؟
  • ما هي أنواع EJB الموجودة؟
سنقوم أيضًا بكتابة تطبيق HelloWorld صغير باستخدام EJB وservlets. تقديم EJB - 1ستكون هذه المقالة مفيدة للقراء الذين أصبحوا مرتاحين مع Java SE وبدأوا في تعلم Java EE. لفهم الجزء العملي من هذه المقالة بشكل كامل، يوصى بقراءة مقال " إعداد البيئة المحلية " أولاً.

تاريخ موجز لـ EJB

في عام 1996، عندما كان مؤلف هذه المقالة يبلغ من العمر 5 سنوات، كانت Java تحظى بشعبية كبيرة بين المطورين. والسبب في ذلك هو واجهة برمجة التطبيقات الودية، وجمع البيانات المهملة تلقائيًا، وما إلى ذلك. تم استخدام Java على نطاق واسع في الأنظمة المسؤولة عن الواجهة الخلفية. ومع ذلك، على الرغم من كل سحر اللغة، كان المبرمجون في ذلك الوقت بحاجة إلى وظائف معينة لم يتم تنفيذها بعد في JDK. وكانت هذه الاحتياجات:
  • ضمان استمرارية البيانات؛
  • سلامة الصفقة
  • الوصول التنافسي إلى البيانات (التحكم متعدد الخيوط)؛
  • وعلى الأرجح شيء آخر.
أدى كل هذا إلى نمو طبيعي في عدد المكتبات المغلقة والمكتوبة محليًا. بمعنى آخر، قام الجميع بتلبية احتياجاتهم بأفضل ما يستطيعون. وذلك حتى خرجت شركة IBM بشعار "يجب على الجميع تلبية احتياجاتهم بنفس الطريقة"، وأصدرت مواصفات Enterprise Java Bean (EJB) في عام 1997. وهذا هو ما جعل من الممكن توحيد عملية التطوير وأخذ حل المشكلات النموذجية (الموصوفة أعلاه كاحتياجات) إلى الإطار. قامت شركة Sun بتكييف من بنات أفكار IBM لمدة عامين، وفي عام 1999 أصدرت مواصفات EJB 1.0. هذه هي الطريقة التي ولدت بها التكنولوجيا، والتي سيتم مناقشتها بشكل أكثر تطبيقًا.

ما هو إي جي بي

EJB بمعنى ما هو مصطلح جماعي، اعتمادًا على السياق، يمكن أن يعني إما تقنية Enterprise JavaBeans نفسها بشكل عام، أو بعض مكونات برنامج Enterprise JavaBean المحددة (الفاصوليا) التي تعد جزءًا من تقنية EJB. يتم تقديم تعريف EJB كتقنية في ويكيبيديا: Enterprise JavaBeans (غالبًا ما يستخدم أيضًا كاختصار EJB) هي مواصفات تقنية لكتابة ودعم مكونات الخادم التي تحتوي على منطق الأعمال. إنه جزء من Java EE. يتم استخدام هذه التقنية عادةً عندما يتطلب منطق الأعمال خدمة واحدة على الأقل من الخدمات التالية، وغالبًا ما تكون جميعها جميعًا:
  • دعم استمرارية البيانات: يجب أن تكون البيانات آمنة حتى بعد إيقاف البرنامج. يتم تحقيق ذلك في أغلب الأحيان باستخدام قاعدة بيانات؛
  • دعم المعاملات الموزعة؛
  • دعم تعديل البيانات الموازية وتعدد مؤشرات الترابط؛
  • دعم الحدث؛
  • دعم التسمية والدليل (JNDI)؛
  • الأمن وتقييد الوصول إلى البيانات؛
  • دعم التثبيت الآلي على خادم التطبيق؛
  • الوصول عن بعد.
الخدمات المذكورة أعلاه هي ميزة لا شك فيها لتقنية EJB. ميزة أخرى هي أن كل ما هو مذكور أعلاه يعمل خارج الصندوق على الفور. أولئك. لا يحتاج المبرمج إلى التفكير في دعم المعاملات الموزعة. يحتاج المبرمج فقط إلى التفكير في منطق العمل الذي يحاول تنفيذه حاليًا. إن EJB كمكون برنامج محدد هو فئة Java مع واحد أو أكثر من التعليقات التوضيحية من مواصفات EJB التي تحتوي على بعض منطق الأعمال الخاص بالتطبيق. التعليقات التوضيحية من مواصفات EJB تمنح الفئة الموسومة صلاحيات وصلاحيات وقوى خارقة معينة. اقرأ المزيد عن هذا أدناه.

أنواع EJB

دعونا نلخص. EJB عبارة عن فئة Java عادية تتميز بأحد التعليقات التوضيحية الخاصة. تسمى هذه الفئات الفاصوليا. اعتمادا على التعليق التوضيحي الذي تم وضع علامة على الفصل، سيكون ممثلا لنوع واحد أو آخر من EJB (الفاصوليا). هناك ثلاثة أنواع رئيسية من الفول:
  • الفاصوليا المدفوعة بالرسالة (الفاصوليا المدفوعة بالرسالة)؛
  • وحدات الكيان - المحددة في مواصفات JPA (Java Persistence API) وتستخدم لتخزين البيانات؛
  • حبوب الجلسة.
وتنقسم هذه الأخيرة (فاصوليا الجلسة) إلى عدة أنواع فرعية:
  • عديمي الجنسية (بدون دولة)؛
  • ذو حالة (مع دعم لحالة الجلسة الحالية)؛
  • مفرد (كائن واحد للتطبيق بأكمله؛ بدءًا من EJB 3.1).
تقديم EJB - 2أدناه سننظر في كل نوع من أنواع الفول بمزيد من التفاصيل.

حبوب الجلسة

حبوب الجلسة، أو حبوب الجلسة، هي نوع محدد من الفول. إنها تقوم بتغليف منطق الأعمال الذي يمكن للعميل استدعاؤه برمجيًا عن طريق استدعاء أساليب الحبة. يمكن لاستدعاء الطريقة القيام بما يلي:
  • محليًا، بواسطة فئة أخرى في نفس JVM مثل حبة الجلسة؛
  • عن بعد، عبر الشبكة، من JVM آخر، باستخدام تقنية Java RMI (Remote Method Invocation).
تعني كلمة "جلسة" أن الوحدة متاحة فقط أثناء قيام الخادم بمهمة محددة ويتم تدميرها بشكل لا رجعة فيه في حالة فشل الخادم أو إيقاف تشغيله. يتم التحكم في دورة حياة مثيل حبة الجلسة بواسطة حاوية EJB (يمكنك قراءة المزيد عن حاويات EJB في المحاضرة الأولى من السلسلة ). لا تقوم حبوب الجلسة عديمة الحالة بتخزين معلومات حول حالتها. يمكن استخدام هذا النوع من المكونات من قبل العديد من العملاء. يتم استخدام الفاصوليا عديمة الحالة لتنفيذ العمليات التجارية التي يمكن إكمالها في عملية واحدة. على سبيل المثال، التحقق من التاريخ الائتماني للعملاء. نظرًا لأنه يمكن استخدام مثيل حبة واحدة من قبل العديد من العملاء، يجب على المطور توفير وصول آمن لمؤشر الترابط إلى بيانات الحبة. يعد إنشاء حبة من هذا النوع (وكذلك جميع حبوب الجلسة الأخرى) أمرًا بسيطًا للغاية. هذه فئة Java عادية مع تعليق توضيحي @Stateless. دعونا نعطي مثالا أدناه:
import javax.ejb.Stateless;

@Stateless
public class StatelessEjbExample {
    public String sayHi() {
        return "Hi, I'm Stateless EJB!";
    }
}
تحتفظ وحدات الجلسة التي تدعم حالة الجلسة الحالية (Stateful) بمعلومات حول حالتها بين الاستدعاءات إليها من نفس العميل وتنهي وجودها بناءً على طلب صريح من العميل. يتم تحقيق ذلك بسبب حقيقة أن الفاصوليا المميزة فريدة لكل عميل. مثال على المهمة التي يمكن أن يكون هذا النوع من الفول مسؤولاً عنها هو إبقاء عربة التسوق في متجر عبر الإنترنت محدثة لكل مستخدم. تتم إدارة دورة حياة هذه الحبوب بواسطة حاوية EJB. يتم تدمير هذه الحبوب أيضًا عند خروج العميل. من السهل أيضًا إنشاء مثل هذه الفاصوليا. هذه فئة Java تم وضع علامة عليها بالتعليق التوضيحي Stateful. المثال أدناه:
import javax.ejb.Stateful;

@Stateful
public class StatefulEjbExample {
    public String sayHi() {
        return "Hi, I,m Stateful EJB";
    }
}
يتم بدء تشغيل حبوب الجلسة المفردة مرة واحدة خلال عمر التطبيق وتظل موجودة طوال عمر التطبيق. تم تصميم هذه الفاصوليا للمواقف التي يجب فيها مشاركة حالة واحدة بين جميع العملاء. مثل الفاصوليا عديمة الحالة، في الفاصوليا المستقلة، يحتاج المطور إلى التأكد من تنظيم البيئة داخل الحبة بطريقة آمنة. دعونا نعطي مثالاً على حبة Singleton، التي يسهل إنشاؤها مثل نظيراتها التي تمت مناقشتها أعلاه. من السهل تخمين أن هذه فئة Java مع التعليق التوضيحي @Singleton. ومع ذلك، في هذه الحالة عليك أن تكون حذرا. هناك نوعان من التعليقات التوضيحية، متطابقة في بناء الجملة، ولكن مختلفة في الغرض وتقع في حزم مختلفة:
  • javax.ejb.Singleton
  • javax.inject.Singleton
لإنشاء EJB، يجب عليك استخدام التعليق التوضيحي من ملف javax.ejb. المثال أدناه:
import javax.ejb.Singleton;

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

رسالة مدفوعة الفاصوليا

تقوم الفاصوليا التي تعتمد على الرسائل، أو MDBs، أو الفاصوليا التي تعتمد على الرسائل، مثل حبوب الجلسة، بتنفيذ بعض منطق الأعمال. ولكن على عكس أقاربه، فإن بنك MDB لديه فارق مهم واحد. لا يقوم العملاء أبدًا باستدعاء أساليب MDB مباشرة. غالبًا ما تعمل هذه الفاصوليا كمستمعين لرسائل JMS (خدمة رسائل Java) وتعمل على تنظيم تبادل الرسائل غير المتزامن بين أجزاء النظام. ومن الأمثلة على هذه الرسالة طلب تسليم المخزون من نظام البيع بالتجزئة الآلي إلى نظام إدارة التوريد. فيما يلي مثال لفاصوليا MDB. على عكس حبوب الجلسة، فإن إنشائها أكثر إثارة للاهتمام قليلاً:
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 الخاصة بنا بمثابة حبة. داخل التعليق التوضيحي، باستخدام JNDI (اقرأ عن JNDI هنا )، يتم تحديد اسم توزيع JMS، والذي يصبح فصلنا مستمعًا له. بالإضافة إلى ذلك، يقوم فصلنا بتنفيذ الواجهة MessageListenerوطريقتها onMessage. سيتم استدعاء هذه الطريقة عند وصول رسالة من قائمة الانتظار/التوزيع بالاسم المحدد داخل التعليق التوضيحي MessageDriven.

حبوب الكيان

جزء من تقنية EJB هو مواصفات JPA. JPA، أو Java Persistence API، عبارة عن مواصفات توفر رسم الخرائط الارتباطية للكائنات (ORM) لكائنات Java (وحدات الكيان) وتوفر واجهة برمجة تطبيقات لتخزين هذه الكائنات واسترجاعها وإدارتها. يسمح لك JPA بتمثيل البيانات من قاعدة البيانات ككائنات Java، بالإضافة إلى حفظ كائنات Java كسجلات في قاعدة البيانات. لا يمكن لكل فئة أن تعمل ككائن كهذا، ولكن وحدات الكيان. Entity Bean هي فئة Java تمثل جدولًا في قاعدة البيانات. يتم تحقيق العرض (رسم الخرائط) من خلال استخدام التعليقات التوضيحية الخاصة. بمساعدتهم، تتم مقارنة فئة Java مع جدول في قاعدة البيانات، وكذلك مقارنة حقول فئة Java مع حقول جدول قاعدة البيانات. فيما يلي مثال لوحدة الكيان، مع التعليقات في الكود:
@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. قبل قراءة هذه المقالة، يوصى بشدة بقراءة المقالة الخاصة بإعداد بيئتك المحلية .
  1. قم بإنشاء مشروع Maven جديد في IntelliJ IDEA.

    ملف -> جديد -> مشروع...

    تقديم EJB - 3
  2. انقر فوق {التالي .

  3. املأ معلمات مشروع Maven:

    تقديم EJB - 4
  4. انقر فوق إنهاء

  5. تم إنشاء المشروع وله الهيكل التالي:

    تقديم EJB - 5
يبدو ملف pom.xml كما يلي: تقديم EJB - 6أولاً، نحتاج إلى إضافة تبعية إلى Java EE API، وكذلك تحديد حزمة مشروعنا في شكل أرشيف تطبيق ويب (حرب). للقيام بذلك، تحتاج إلى تغيير كود pom.xml إلى النموذج التالي:
<?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. ستكون هذه حبة جلسة عديمة الحالة. داخل EJB، سنحدد طريقة واحدة فقط ستعيد السلسلة "Hello World". أولاً، لنقم بإنشاء حزمة com.javarush.lectures. بعد ذلك، داخل الحزمة com.javarush.lectures، سنقوم بإنشاء الفول الخاص بنا - DemoEJB. رمز الفول موضح أدناه:
import javax.ejb.Stateless;

@Stateless
public class DemoEJB {
    public String helloWorld() {
        return "Hello world!";
    }
}
كما قلنا سابقًا، كل شيء بسيط جدًا. خطوتنا التالية هي إنشاء servlet الذي سيقوم بتمرير القيمة من وحدة جافا للأعمال كاستجابة لطلب HTTP. تجدر الإشارة إلى أن servlets ليست موضوع هذه المقالة، لكنك ستظل بحاجة إلى استخدامها لشرح وحدة جافا للأعمال. للقيام بذلك، دعونا نقوم بإنشاء servlet جديد 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")- يعرّف فئتنا بأنها servlet الذي سيقوم بمعالجة طلبات HTTP إلى نقطة النهاية /helloWorld. يحتوي فصلنا على حقل واحد - DemoEJB ejb. هذه هي حبة الفول التي تم تعريفها مسبقًا. تعليق توضيحي على حقل فئة - @EJBينفذ حقن التبعية (DI). أولئك. تتم تهيئة المتغير ejb تلقائيًا بمثيل جديد عند الحاجة. فئتنا هي سليل HttpServlet وتتجاوز إحدى طرق الطبقة الفائقة - doGet. تعالج هذه الطريقة طلبات HTTP GET وتأخذ معلمتين - HttpServletRequestو HttpServletResponse. HttpServletRequestيعمل على الحصول على معلومات حول طلب HTTP وارد. HttpServletResponseاللازمة لتوليد استجابة لطلب. داخل الطريقة، نحصل على الكائن PrintWriterمن كائن الاستجابة ( HttpServletResponse)، باستخدام getWriter(). بعد ذلك، يمكننا كتابة بعض القيمة للكائن الناتج باستخدام الملف write. وهو في الواقع ما نستخدمه من خلال الكتابة في PrintWriterالكائن -a القيمة التي تم الحصول عليها من EJB التي حددناها (القيمة هي السلسلة "Hello World!"). سيتلقى العميل الذي أرسل طلب HTTP هذه القيمة كرد على طلبه. الخطوة التالية هي تشغيل التطبيق على خادم GlassFish Java EE. للقيام بذلك، سنقوم بإنشاء تكوين جديد، كما هو موضح في المقالة حول إعداد البيئة المحلية . فيما يلي لقطة شاشة للتكوين النهائي للمشروع الحالي. تأكد من تثبيت خادم GlassFish قبل البدء: تقديم EJB - 7بعد إنشاء تكوين التشغيل، قم بتشغيل التطبيق باستخدام القائمة Run -> Run 'ejb_demo' أو باستخدام مفتاح التشغيل السريع Shift+F10 . بعد الإطلاق، يمكنك رؤية سجلاته: تقديم EJB - 8وكذلك المتصفح الذي يفتح: تقديم EJB - 9كل هذا يشير إلى أن التطبيق يعمل على النحو المنشود.

خاتمة

في هذه المقالة تعرفنا على EJB - Enterprise JavaBeans. لقد نظرنا في أسئلة مثل:
  • ما هو إي جي بي؟
  • تاريخ إي جي بي
  • أنواع مختلفة من EJBs
تذكر أن EJBs تأتي في الأنواع التالية:
  • الفاصوليا المدفوعة بالرسالة (الفاصوليا المدفوعة بالرسالة)؛
  • وحدات الكيان - المحددة في مواصفات كيانات JPA (Java Persistence API) والمستخدمة لتخزين البيانات؛
  • حبوب الجلسة:
    • عديمي الجنسية (بدون دولة)
    • ذو حالة (مع دعم لحالة الجلسة الحالية)
    • مفرد (كائن واحد للتطبيق بأكمله؛ بدءًا من EJB 3.1)
لقد كتبنا أيضًا تطبيق HelloWorld صغيرًا باستخدام EJB. باعتبارك PD، يمكنك تكرار الجزء العملي من هذه المقالة بنفسك. ثم قم بإضافة اثنين من servlets إلى تطبيقك الذي سيستخدم وحدات الحالة والفاصوليا المفردة لتلقي القيمة.
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION