ملخص ستناقشك هذه المقالة كيفية الجمع بين قوة التعليقات التوضيحية والجوانب لتوفير الخدمات التعريفية للمؤسسات بطريقة متوافقة مع EJB 3.0 مع الاستمرار في توفير استقلال الحاويات.
1. مقدمة
في سعينا المشترك لطرق لتحسين أداء إنتاج تطوير البرمجيات ، ننتقل - كأعضاء في مجتمع Java - عمومًا إلى J2EE لتوفير مشكلات فنية أكثر تحديًا في تطوير المؤسسات مثل إدارة المعاملات الموزعة ، وحلول توزيع التزامن وتوزيع الكائنات. تعتبر الإيديولوجية التوجيهية التي تقف وراءها - يمكن تنفيذ خدمات المؤسسات المعقدة هذه من قبل بائعي خادم التطبيقات ومتوازنة من قبل المطورين التجاريين - فكرة جيدة بالفعل. لقد نجحت J2EE ، وتحديداً EJB ، في توفير منصة تم بناء تطبيقات Java للمؤسسة.
يرجع جزء من هذا النجاح إلى القدرة على أداء البرمجة التصريفية - وهي طريقة لتطوير برنامج - يمكنك من خلاله إعلان خدمات البنية التحتية بدلاً من الترميز بشكل صريح مع منطق العمل بحيث يتم نشر الرمز في كل مكان. لقد أثبت EJB قيمة نهج البرمجة هذا - من خلال السماح بإعلان مشكلات المؤسسات مثل المعاملات والأمان مع واصف النشر ومعالجته بواسطة حاوية.
ومع ذلك ، على مدار السنوات الماضية ، أدرك المزيد والمزيد من المطورين أن EJB يجلب الكثير من التحديات الجديدة في إنتاجية الفريق - يجب أن يكون كل EJB مصحوبًا بواجهات متعددة ، مع وصف واصف نشر ، تم الوصول إليه عبر JNDI ، إلخ. يجلب اختبار الوحدة على EJB خارج الحاوية صعوبات إضافية.
يرجى ملاحظة أنه من أجل قراءة هذه المقالة ، تحتاج إلى الحصول على الأدوات التالية:
· Java 2 SDK 1.5
· Maven 2.0 Beta 2
الهدف من EJB 3.0 هو جعل تطوير المؤسسة أسهل في الجوانب التالية:
· تنفيذ الطلبات التعريفية لخدمات المؤسسات من خلال تقديم تعليقات التعليقات الوظيفية
· تنفيذ التبعية/حقن الموارد عبر التعليق التوضيحي
· تنفيذ فصل حبوب المؤسسة وواجهات محددة EJB
· تبسيط التخزين المستمر من خلال رسم خرائط للكائنات خفيفة الوزن
هذا يشبه نسيم الربيع لمطوري EJB - لقد كانوا يعملون بجد لتطوير واختبار وصيانة EJB. أصبح من السهل الآن كتابة حبة مؤسسة باستخدام EJB 3.0 ، تمامًا مثل إنشاء POJO (كائن Java التقليدي) مع تعليقات محددة لتمييزها على أنها خدمات EJB وطلب المؤسسات. فيما يلي مثال من EJB في المسودة العامة EJB 3.0:
stateful
يقوم Cartbean من الطبقة العامة بتنفيذ CarpingCart
{
إجمالي تعويم خاص ؛
رموز منتجات المتجهات الخاصة ؛
العام int someshoppingmethod () {...} ؛
...
}
ينص بيان EJB 3.0 بشكل أساسي على أن ما يحتاجه المطورون ليس حلًا ثقيلًا ، "إصدار واحد يرضي كل شيء" ، ولكنه حل خفيف الوزن وسهل الاستخدام-يوفر للمطورين مجموعة معينة من خدمات المؤسسات. تحقيقًا لهذه الغاية ، تتمثل إحدى أهم الطرق التي توفرها EJB 3.0 في فصل حبوب المؤسسات وواجهة برمجة التطبيقات EJB. وهذا الحل يجلب أيضًا مشتقات مثيرة للاهتمام - يمكن الآن تشغيل EJB ليس فقط على حاويات EJB المختلفة ، ولكن أيضًا داخل أي إطار تطبيق - يجب أن تكون هذه الأطر قادرة على التعرف على EJB 3.0 (JSR 220) والشرح الطبيعي لإعلان خدمات المؤسسات (JSR 250) .
لا توفر هذه المقالة استكشافًا متعمقًا للبرمجة التعريفية أو EJBs أو الجوانب أو التعليقات التوضيحية. بدلاً من ذلك ، فقط قم بتحليل العلاقات المتبادلة بين هذه التقنيات ومناقشة كيفية الجمع بينها بطريقة جديدة لتبسيط تطوير التطبيق.
في هذه المقالة ، سوف تتعلم كيفية كتابة حبة متوافقة مع EJB 3.0 وإنشاء عدة جوانب بسيطة لجعلها إدارة معاملات التصريح والأمن وحقن الموارد. آمل أن تتمكن من الاستفادة من هذا التمرين:
· ثلاثة تطبيقات عملية في التعلم (حقن التبعية والأمن والمعاملات).
· على دراية بـ EJB 3.0 والأفكار وراء ذلك.
تعرف على كيفية تنفيذ فصل EJB من واجهات برمجة التطبيقات المحددة للسماح بتنفيذ خدمات متوافقة مع EJB 3.0 في الوزن الخفيف بدلاً من توفير EJB فقط.
2. مثال طلب طيران التطبيق
خلال المناقشة ، ستتعرف على تنفيذ نظام ترتيب الطيران - والذي يستخدم الجوانب والشروح لتنفيذ حقن التبعية ، والأمان ، وإدارة المعاملات. يقوم التطبيق بوظيفة فقط: يسمح للمستخدمين بالبحث عن الرحلات الجوية (الشكل 1) ثم طلب رحلة (الشكل 2). ستتم معالجة كلتا العمليتين بشكل آمن للسماح للمستخدمين المحددين فقط بتنفيذها. بالإضافة إلى ذلك ، نظرًا لأن عملية "Trade Travel" تتضمن طلب رحلتين (رحلات خارجية وعودة) ، يجب إنشاء العملية على أنها معاملات - على سبيل المثال ، سوف ينجح كلا الطلبات أو فشلهما كوحدة عمل.
الشكل 1. استعلام الطيران: أولاً ، يبحث المستخدمون عن الرحلات الجوية التي تلبي معاييرهم المحددة.
الشكل 2. ترتيب الرحلة: بعد ذلك ، يأمر المستخدم برحلة خارجية ورحلة عودة. كلا الطلبات إما تنجح أو تفشل.
يحتوي تطبيق الويب البسيط هذا على العديد من servlets ومظهر خدمة وطبقة DAO (انظر الشكل 3).
سيتم توفير المخاوف المتقاطعة مثل تكوين الموارد والأمان وإدارة المعاملات من خلال الجوانب (التي يتم تنفيذها مع SAFFEJ 1.5 M3) لتنفيذ سلوك الحقن المعلن في التعليقات التوضيحية Java 5.
الشكل 3. بنية نظام طلب الطيران: يتكون نظام طلب الرحلة هذا من ثلاثة مكونات رئيسية - ينضمون معًا لإكمال طلبات المستخدم. 3. حقن الموارد
يسمح مسودة إعلان EJB 3.0 بإعلان الموارد عبر شرح @Resource (يتم تعريف هذا القرار في مسودة إعلان التعليقات التوضيحية العادية) وحقنها في EJB بواسطة الحاوية. حقن التبعية هو تقنية - باستخدام هذه التقنية ، يمكن أن يوفر كيان خارج كائن بدلاً من كيان تم إنشاؤه بشكل صريح لهذا الكائن (حقن) تبعية كائن. يتم وصفه أحيانًا على أنه مبدأ هوليوود - الذي ينزلق مثل "لا تتصل بنا ، سنتصل بك".
خذ فئة TravelagencyServiceImpl كمثال - من أجل تخزين بعض البيانات بشكل مستمر ، تحتاج هذه الفئة إلى العثور على تنفيذ واجهة IFLISTDAO. تقليديا ، يتم تحقيق ذلك من خلال مصنع أو مفردة أو محدد خدمة أو حل مخصص آخر. من بينهم ، يبدو أحد الحلول الممكنة مثل هذا:
الطبقة العامة travelagencyserviceimpl تنفذ ittravelagencyservice
{
عام Iflightdao FlightDao ؛
TravelagencyServiceImpl ()
{FlightDao = FlightDaofactory.getInstance (). getFlightdao () ؛
Booktrip public void (Long OutboundFlightid ، عودة طويلة ، مقاعد INT)
يلقي perileSeateSexception
{
Ceserveseats (OutboundFlightId ، مقاعد) ؛
Ceserveseats (ReturnFlightId ، مقاعد) ؛
}
}
لقد رأيت أن هذا التنفيذ يتضمن إنشاء فئة مصنع معينة - من المحتمل أن تقرأ معلومات التكوين المخزنة في مكان ما لفهم كيفية إنشاء تطبيق IFLISTDAO. إذا لم تكن الخدمة تنشئ بشكل صريح تبعياتها التي يتم حقنها بواسطة الحاوية ، فسيتم تفصيل تفاصيل التكوين وإنشاء الكائن إلى الحاوية. يتيح ذلك توصيل المكونات في التطبيق بسهولة - مع تكوينات مختلفة ويزيل الكثير من كود المفرد والفرض القديم.
قد يبدو تنفيذ الفصل - الذي يعتمد على تنفيذ IFLISTDAO المعلن عن توضيح الموارد JSR 250 - هكذا:
الطبقة العامة travelagencyserviceimpl تنفذ ittravelagencyservice
{
Resource (name = "FlightDao")
عام Iflightdao FlightDao ؛
Booktrip public void (Long OutboundFlightid ، عودة طويلة ، مقاعد INT)
يلقي perileSeateSexception
{
Ceserveseats (OutboundFlightId ، مقاعد) ؛
Ceserveseats (ReturnFlightId ، مقاعد) ؛
}
}
في هذه الحالة ، ستوفر الحاوية التنفيذ الصحيح لمورد يسمى "FlightDao" إلى فئة الخدمة. ولكن ماذا لو كنت ترغب في الاستفادة من حقن الموارد الآن بدلاً من انتظار إصدار EJB 3.0؟ حسنًا ، يمكنك تناول حاوية خفيفة الوزن - فهي قادرة على توفير حقن التبعية مثل حاوية الربيع أو PICO. ومع ذلك ، لا أفهم أن هناك حاوية خفيفة الوزن - فهي قادرة على استخدام شرح موارد JSR 250 لتحديد متطلبات الحقن (على الرغم من أنني أتطلع إلى بعض في هذا الصدد).
أحد الحلول هو استخدام الجوانب لتنفيذ حقن التبعية. إذا كنت تستخدم شرح Resource لهذا ، فسيكون تنفيذك متسقًا مع طريقة EJB 3.0 وإلى الأمام المتوافقة مع تطبيق EJB 3.0 - وهذا ليس بالأمر الصعب للغاية. تعرض القائمة التالية جانبًا تم إنشاؤه مع SideJ - يقوم بحقن الحقول المشروحة بشرح @Resource:
@وجه
حقن الطبقة العامة
{
مدير التبعية الخاصة = New DependencyManager () ؛
before ("get (ersource * *. *)")
الفراغ العام قبل الوصول إلى FieldScesses (Joinpoint thisjoinpoint)
يلقي alfictalargumentexception ، inchlessalaraccessexception
{
توقيع FieldSignature = (FieldSignature) thisjoinpoint.getSignature () ؛
Resource enjectannotation = signature.getfield (). getAnnotation (Resource.Class) ؛
الاعتماد على الكائن = MANGER.RESESSERNING (signature.getfieldtype () ، enjectannotation.name ()) ؛
Signature.getField ().
}
}
كل هذا الجانب البسيط هو الاستعلام عن فئة التنفيذ من ملف خاصية (يتم تغليف هذا المنطق في كائن DependencyManager) وضخه في الحقول المشروحة بتعليقات Resource قبل الوصول إلى الحقل. من الواضح أن هذا التنفيذ غير مكتمل ، لكنه يوضح كيف يمكنك توفير حقن الموارد بطريقة متوافقة مع JSR 250 بدون EJB.
4. السلامة
بالإضافة إلى حقن الموارد ، يوفر JSR 250 و EJB 3.0 أيضًا تمثيلًا آمنًا لبيانات الوصفية عبر التعليقات التوضيحية. تحدد حزمة javax.annotation.security خمسة تعليقات توضيحية - Runas ، Rolesally ، perferal ، Denyall و Rolesreference - يمكن تطبيقها على أساليب لتحديد متطلبات الأمان. على سبيل المثال ، إذا كنت تريد أن تعلن أنه لا يمكن تنفيذ طريقة Bookflight المدرجة أعلاه إلا من قبل المتصلين مع دور "المستخدم" ، فيمكنك التعليق على هذه الطريقة مع قيود الأمان التالية:
الطبقة العامة travelagencyserviceimpl تنفذ ittravelagencyservice
{
Resource (name = "FlightDao")
عام Iflightdao FlightDao ؛
ROLOLOLLED ("المستخدم")
Booktrip public void (Long OutboundFlightid ، عودة طويلة ، مقاعد INT)
يلقي perileSeateSexception
{
Ceserveseats (OutboundFlightId ، مقاعد) ؛
Ceserveseats (ReturnFlightId ، مقاعد) ؛
}
}
سيوضح هذا التعليق التوضيحي أن الحاوية مسؤولة عن ضمان أن المتصل فقط للدور المحدد يمكنه تنفيذ هذه الطريقة. الآن سأظهر جانبًا بسيطًا آخر - سيؤدي إلى زيادة تعزيز القيود الأمنية على التطبيق:
@وجه
أمن الطبقة العامة
{
around ("التنفيذ (@javax.annotation.security.rolesallowed * *. *(..))")
كائن عام حول methods (proceedingjoinpoint thisjoinpoint)
رمي رمي
{
Boolean callerauthorized = false ؛
rolesallowed rolesallyed = rolesallyedforjoinpoint (thisjoinpoint) ؛
لـ (دور السلسلة: ROLEOLOLOLED.VALUE ())
{
إذا (Callerinrole (دور))
{callerauthorized = true ؛
}
إذا (callerauthorized)
{return thisjoinpoint.proceed () ؛
آخر
{
رمي جديد RunTimeException ("المتصل غير مصرح لأداء وظيفة محددة") ؛
}
}
ROLESERED ROLESERNOLDFORJOINPOINT (POSTROPENGOINPOINT TESJOINPOINT)
{
methodsIcsIrgenature comply = (MaysIngureature) thisjoinpoint.getSignature () ؛
طريقة TargetMethod = MethodySignature.getMethod () ؛
إرجاع targetmethod.getAnnotation (Rolesallowed.class) ؛
}
Callerinrole المنطقية الخاصة (دور السلسلة)
{...}
}
يتضمن هذا الجانب تنفيذ جميع الأساليب - من خلال التحقق من أن المتصل هو أحد الأدوار المحددة في التعليق التوضيحي ، وتوضيح مع التعليق التوضيحي @ROLOLOLOLID وضمان أن يكون المتصل مخولًا للاتصال بالطريقة. بالطبع يمكنك أيضًا استخدام أي خوارزمية ترغب في تفويض المستخدم واسترداد دوره/دوره ، مثل JAAS أو حل مخصص. في برنامج المثال ، للراحة ، اخترت الوكيل إلى حاوية Servlet.
خامسا الشؤون
تصبح المعاملات جزءًا مهمًا من تطوير المؤسسات - لأنها تسهل تكامل البيانات في بيئة متزامنة. من المستوى العالي ، يمكن للمعاملات ضمان ذلك من خلال عمليات متعددة أو كاملة أو غير مكتملة.
على عكس التعليقات التوضيحية لحقن الموارد والأمن ، فإن التعليقات التوضيحية للمعاملات خاصة بـ EJB 3.0 ولا يتم تعريفها في التعليقات التوضيحية الطبيعية JSR 250. يحدد EJB 3.0 اثنين من التعليقات التوضيحية المرتبطة بالمعاملات: إدارة المعاملات والمعاملات. يحدد شرح TransactionManager ما إذا كان يتم إدارة المعاملة بواسطة الحاوية أو بواسطة الفول. في EJB 3 ، إذا لم يتم تحديد هذا التعليق التوضيحي ، فسيتم استخدام المعاملة التي تديرها الحاوية. يتم استخدام شرح التعليقات المعاملة لتحديد مستوى انتشار المعاملة للطريقة. يتم استخدام القيم الصالحة - بما في ذلك الإلزامية والمطلوبة والمطلوبة الجديدة أو المدعومة وغير المدعومة ولا تدعمها أبدًا - لتحديد ما إذا كانت المعاملة الحالية مطلوبة أو تم بدء معاملة جديدة ، إلخ.
نظرًا لأن عملية Bookflight تتكون من خطوتين - طلب رحلة خارجي ورحلة عودة ، عن طريق تعبئتها في معاملة ، يمكنك ضمان اتساق العملية. باستخدام تعليقات المعاملات EJB 3.0 ، سيبدو هذا هكذا:
الطبقة العامة travelagencyserviceimpl تنفذ ittravelagencyservice
{
Resource (name = "FlightDao")
عام Iflightdao FlightDao ؛
ROLOLOLLED ("المستخدم")
transactionAttribute (TransactionAttributePe.Required)
Booktrip public void (Long OutboundFlightid ، عودة طويلة ، مقاعد INT)
يلقي perileSeateSexception
{
Ceserveseats (OutboundFlightId ، مقاعد) ؛
Ceserveseats (ReturnFlightId ، مقاعد) ؛
}
}
ويمكنك تطبيق جانب بسيط لتحديد حدود المعاملات تلقائيًا:
@وجه
المعاملات من الطبقة العامة
{
@pointcut ("التنفيذ (@javax.ejb.transactionAttribute * *. *(..))")
الفراغ العام معاملة almethods () {}
before ("TransactionAlmethods ()")
الفراغ العام beforetransactionalmethods ()
{hibernateutil.begintransaction () ؛
AfterReturning ("TransactionAlmethods ()")
الفراغ العام بعد الإثارة
{hibernateutil.committransaction () ؛
AfterThroing ("TransactionAlmethods ()")
الفراغ العام بعد remrowingtransactionalmethods ()
{hibernateutil.rollbacktransaction () ؛
}
يعتمد هذا التنفيذ على افتراض أن النمط المحلي للمعاملات في كل مكان لإدارة جلسات السبات وكائنات المعاملات ؛
6. ملخص
باستخدام مجموعات التعليقات التوضيحية EJB 3.0 و JSR 250 ، أظهرت هذه المقالة كيف يتم تنفيذ المخاوف المتقاطعة مثل إدارة الموارد والأمن والمعاملات كجوانب. بالطبع ، هناك العديد من المحتويات الأخرى التي نحتاج إلى معرفة المزيد. أول شيء يجب تعلمه هو المخطط الذي توفره المخاوف المتقاطعة المعيارية من خلال تنفيذ هذه الجوانب المثال باستخدام SideJJ. ثانياً ، لقد رأينا بعض الأفكار والمفاهيم الجديدة وراء بيان EJB 3.0 الذي ظهر الآن. أخيرًا ، نرى أيضًا بطريقة مثيرة الحرية التي يجب توفيرها لفصل أشياء أعمالنا من API EJB. في هذه المرحلة ، كل ما تريد جعل TravelagencyServiceImpl جلسة عديمية هو القيام بها هو إضافة ملاحظة أخيرة:
stateful
الطبقة العامة travelagencyserviceimpl تنفذ ittravelagencyservice
{...}
أخيرًا ، آمل حقًا أن يجلب هذا النهج المجاني لتوفير خدمات المؤسسات المنافسة والابتكار في صناعة الإطار/الحاويات.