ملخص
بالنسبة لمطوري الويب ، فإن نموذج MVC مألوف جدًا للجميع. في springMVC ، يدخل الطلب الذي يلبي الشروط المرسلة المسؤولة عن توزيع الطلب. يقوم Dispatcherservlet بتخطيط عنوان URL للطلب إلى وحدة التحكم (باستثناء في معالجة). تُرجع المعالجة أخيرًا إلى HandleRexecutionChain ، والتي تحتوي على معالج كائن المعالجة المحدد (أي ما كتبناه عندما نبرمجه). وحدة تحكم) وسلسلة من التقاطعات. في هذا الوقت ، ستجد Dispatcherservlet عبارة عن معالج يدعم نوع المعالج هذا استنادًا إلى المعالج في المعالج في HandleRexecutionchain الذي تم إرجاعه. في محول المعالج ، سيتصل في النهاية بأسلوب استجابة طلب وحدة التحكم وإرجاع عرض النتيجة (ModelandView). بعد الحصول على عرض النتيجة ، يتم عرض النتيجة من خلال طريقة العرض.
نظام الميراث المتداول:
يطلب SpringMVC توزيع معالج المعالج. يتم حل هذه الخطوة من خلال وحدة معالجة. يعالج المعالجة أيضًا اعتراضات.
دعونا نلقي نظرة على شجرة الميراث من المعالجة أولاً
يمكنك عمل تصنيف مثل هذا:
1.
2. فئة مجردة أساسية: إعداد بيئة السياق بشكل أساسي ، يوفر خطاف Gethandlerinternal ، ويغلف التقاطع إلى HandleRexecutionchain
3. استخدام Controller ، requestmapping على أساس التعليق التوضيحي
4. قم بتكوين SimpleUrlhandlerMapping من عنوان URL إلى المعالج في ملف التكوين
5. يتم تنفيذ BeannameUrlhandlerMapping افتراضيًا
6. رسم خرائط للفئات الفرعية تحكم
دعنا نلقي نظرة على معالجة عناد معدات ، مجرد واجهة برمجة تطبيقات Gethandler بسيطة للغاية.
// handlermappingPackage org.springframework.web.servlet ؛ الواجهة العامة معلية {handlexecutionchain gethandler (طلب httpservletrequest) رمي الاستثناء ؛} Abstracthandlermapping ليس بهذه البساطة
انظر أولاً إلى الفصل الموروث بواسطة Abstracthandlermapping وتنفيذ الواجهة
Package org.springframework.web.servlet.handler ؛ فئة مجردة عامة AbracthandLermapping يمتد WebapPlicationObjectSupportImplement
يتم استخدام WebAppLicationObjectSupport لتوفير Context ApplicationContext و ServletContext.
هناك أيضًا طريقة initapplicationContext هنا ، والتي تستخدم غالبًا في المستقبل. تم تجاوز Abstracthandlermapping مباشرة.
لا تزال واجهات ApplicationContextAware و ServletContextAware يتم تنفيذها في الفئة الأصل ، ومفهوم الربيع موحد للغاية.
يتم استخدام الطلب لفرز التجميع.
دعنا نستمر في النظر إلى خصائص Abstracthandlermapping
// abstracthandlermapping // order يعين الحد الأقصى للقيمة ، والأولوية هي أصغر int int = integer.max_value ؛ // الافتراضي: مثل المعالج غير المرتب // الافتراضي ، OBEJCT المستخدمة هنا وتنفيذ الفئة الفرعية ، استخدم معالجتها ، HandleRexecutionChain وغيرها من الكائنات الخاصة defaulthandler ؛ // فئة مساعدة لحساب url private urlpathhelper = new urlpathelper () antpathmatcher () ؛ // التكوين التقاطع: ، ، إعداد خاصية التداخل ، ، قم بتوسيع المقاطعات تعيين القائمة النهائية الخاصة <Bounds> interceptors = new ArrayList <Object> () ؛ // parse من Interceptors وإضافتها مباشرة إلى القائمة النهائية للمعالج <HandlerInterceptor> exedItroptors = new arrayListor <HandlerInterceptor> سيتم استخدام القائمة النهائية الخاصة <MedInterBotceptor> mappedInterceptors = جديد ArrayList <mediPterceptor> () ؛
تحقق من تهيئة التقاطع:
. {}/*** قم بفحص المقاطعات المعينة أسفل التطبيق وأضفها إلى مقبولات mediPtiptors*/proted void detectmappedors (list <MedInterceptor> mediPtistroptors) {mediPterceptors.Addall (beanfactoryutils.beansoftypeincludencestors (getapplicalicalcontext (). false) .values ()) ؛}/*** جمع مقبول mappedInteriptor والتكيف مع المعالج و webrequestinterceptor*/proted void initiproceptors () {if (! this. NULL) {رمي جديد alfulalArgumentException ("رقم الإدخال" + i + "في صفيف اعتراضات هو فارغ") ؛} if (مثيل اعتراض من mediPterceptor) {mediPtropceptors.add ((mappedInterceptor) interceptor) ؛ AdaptInterceptor (اعتراض الكائن) {if (interceptor مثيل من HandlerInterceptor) {return (HandlerInterceptor) interceptor ؛} آخر إذا (Interceptor مثيل webRequestInterceptor) interceptor.getClass (). getName ()) ؛}}ثم هناك تنفيذ Gethandler (طلب httpservletrequest) ، وهنا يحتفظ أيضًا Gethandlerinternal (طلب httpservletrequest) لتنفيذ الفئة الفرعية.
. String) {String HandlerName = (String) Handler ؛ Handler = getApplicationContext (). getBean (معالجة) ؛} إرجاع GethandleRexecutionchain (معالج ، طلب) ؛} محمي كائن مجردة gethandlerinternal (httpservletrequest request) trows ؛ أخيرًا ، قم بتغليف التقاطع إلى HandleRexecutionChain
أضف مقبولات مقتبسة مباشرة
يجب إضافتها إلى الإضافة بعد المطابقة وفقًا لعنوان URL
// AbstracthandlermappingProtected HandleRexecutionchain GethandleRexecutionchain (معالج الكائن ، طلب httpservletrequest) {handleRexecutionchain chain = (Handler extorly of HandleRexecutionchain) معالج: chain.addInterceptors (getAdaptedInterceptors ()) ؛ سلسلة lookuppath = urlPathHelper.getLookuppathforrequest (طلب) ؛ لـ (mediPtroptor mediptopptor: mappedInterceptors) {if (mediNterceptor.matches (pathuppath ، pathmatcher)) سلسلة؛} تعيين فئات فرعية من وحدة التحكم ، يبحث هذا الفرع أولاً في ميراث الفصل
دعنا نتحدث عن المسؤوليات الرئيسية لكل فئة هنا
1. توفير خطاف Gethandlerintern. تغليف التقاطع إلى HandleRexecutionChain
2. التجريدة urlhandlermapping تنفذ طريقة تسجيل المعالج لاستخدام الفئة الفرعية ؛ ينفذ Gethandlerinternal ، ويجد معالجًا استنادًا إلى معلومات التكوين التي تم تهيئتها بواسطة الفئات الفرعية.
3. AbstractDetectingUrlhandlerMapping يقوم بمسح الكائن الموجود تحت التطبيق ، وبعد التكرار ، توفر طريقة الخطاف المحددة لتحديد كيفية تصفيةه.
4. أدوات ActussControllerRlermapping DensionUrlsForHandler ، يضيف عملية المعالج (تكوين ملف التكوين) ، ويحتفظ بطريقة الخطاف buildurlsforhandler لتنفيذ الفئة الفرعية ؛ في الوقت نفسه ، يحكم الفئة الفرعية من المراقب
5. ControlRebeanNameHandLermapping توليد عنوان URL بناءً على اسم الفول
ControlRclassNameHandLermapping يولد عنوان URL بناءً على اسم الفصل
لنبدأ بـ AbstractUrlhandlerMapping. هنا ننظر فقط إلى الكود تقريبًا. إذا كنت بحاجة إلى تحليله بعناية ، فيرجى الانتقال إلى <springmvc تفسير رمز المصدر - معالجة - توزيع طلب سلسلة التجريبي.
تسجيل المعالج
registerHandler المحمي المحمي (String [] urlpaths ، سلسلة beanname) يلقي beansexception ، alfarkalStateException {} محمية void registerHandler (urlpath string ، معالج الكائن) يلقي beansexception ، alfortalstateException {} البحث عن معالج
كائن محمي Gethandlerinternal (طلب httpservletrequest) يلقي استثناء {} // البحث عن معالج الكائنات lookuphandler (urlpath string ، httpservletrequest طلب) استثناء {} HandleRexecutionchainProtected Object BuildPathexPositingHandler (الكائن RawHandler ، سلسلة BestMatchingPattern ، مسار السلسلة ، خريطة <سلسلة ، سلسلة> uritemplatevariables) {}AbstractDetectingUrlhandLermapping ، هذا لم يتم توسيعه ، يرجى التحرك بالتفصيل <springmvc تفسير الكود المصدر - معالجة - التهيئة سلسلة التجريبية.
ما يجب القيام به:
1. مكالمات الكشف عن أجهزة الكشف عن مسح OBJCT عن طريق الكتابة فوق initapplicationContext
2. توفير طريقة الخطاف المحددات forndhandler إلى الفئة الفرعية إنشاء عناوين URL وفقًا للمعالج
3. اتصل بـ RecordHandler من فئة الوالدين للتسجيل
OverRidepublic void initapplicationContext () يلقي ApplicationContextexception {super.initapplicationContext () ؛ detectHandlers () ؛} محمية void detecthandlers () remsexception {// ...}/*** حدد URLs for Handledler Bean. AbstractControllerUrlherlerMapping ، هذا لم يتم توسيعه ، يرجى التحرك بالتفصيل <springmvc تفسير الكود المصدر - معالجة - التهيئة سلسلة التجريبية. ماذا تفعل على وجه التحديد ؛
1. الكتابة فوق تحديد recondurlsforhandler لإضافة منطق لإزالة بعض الفئات ، واستخدام Convedclasses و expludedpackages التي تم تكوينها في ملف التكوين.
2. تحديد ما إذا كانت الفئة الفرعية لوحدة التحكم
3. Buildurlsforhandler
OverRideProtected String [] تحديد urlsforhandler (سلسلة beanname) {class beanclass = getApplicationContext (). beanclass) {} محمية boolean isControllerType (فئة beanclass) {} سلسلة مجردة محمية [] buildurlsforhandler (سلسلة beanname ، الفئة بينكلاس) ؛ ControlRebeanNameHandLermapping و ControlRclassNameHandLermapping انظر إلى الكود المصدرية مباشرة ، أو انتقل إلى <springmvc تفسير رمز المصدر - معالجة - acctionDetectingUrlermapping Series تهيئة> يقوم SimpleUrlHandLermapping بتكوين عنوان URL مباشرة إلى المعالج في ملف التكوين ، والذي يهدف إلى استخدام RecordHandlers لتسجيل المعالج في مستند التكوين ، وقراءة الكود مباشرة أو نقل <springmvc تفسير رمز مصدر - معالجة - تهيئة SimplyUrlhandlermapping>
أدوات BeannameUrlhandLermapping التي تحدد reachurlsforhandler لإنشاء عناوين URL ، انظر إلى الكود مباشرة أو تحرك <springmvc تفسير رمز المصدر - معالجة - acctionDeteCtingUrlermapping Series تهيئة>
استخدام controller ، @requestmapping على أساس التعليق التوضيحي
أصعب عظام
دعونا نلقي نظرة على ميراث الفصل أولاً
دعنا نتحدث عن مسؤوليات كل فئة. لتحليل محدد ، يرجى الانتقال إلى المقالة التالية
<springmvc تفسير رمز المصدر - معالجة - requestMappingHandLermapping التهيئة>
<springmvc تفسير رمز المصدر - معالجة - requestMappingHandLermapping Distribution>
1.
التهيئة:
1.1.1 مسح الكائن أسفل التطبيق
1.1.2 حجز طريقة ربط Ishandler إلى الفئة الفرعية لتحديد ما إذا كان الكائن هو المعالج
1.1.3 مسح تكراري كل معالج للعثور على طريقة تلبي المتطلبات. لا يزال الحكم هنا يترك للفئة الفرعية لتنفيذ getMappingFormeThod
1.1.4 عند تسجيل المعالج الموجود ، تحتاج إلى التأكد
1.1.5 احصل على عنوان URL وفقًا لظروف المطابقة ، والشيء نفسه هو فقط لتحديد العملية. يتم ترك الخوارزمية المحددة للفئة الفرعية لتنفيذ getMappAthpatterns
طلب معالجة التوزيع:
1.2.1 طريقة مطابقة السلسلة المباشرة ، ابحث عن معالج
1.2.2 البحث عن حالة المطابقة ، يتم تسليم الخوارزمية المحددة هنا إلى الفئة الفرعية إلى GetMatchingMapping
1.2.3 فرز والحصول على أفضل معالج مطابقة. طريقة الفرز هنا لا تزال معالجة الفئة الفرعية getMappingCarparator
1.2.4 تغليف المطابقة وعدم مطابقة المعالجات على التوالي
2. requestMappingInfoHandLermapping يستخدم requestMappingInfo لتنفيذ شروط المطابقة ، ويتم ترك تهيئة requestmappingInfo إلى الفئة الفرعية
2.1 إنشاء عنوان URL -> getMappPathpatterns وفقًا لـ requestMappingInfo
2.2 ابحث عن معالج باستخدام شروط المطابقة -> getMatchingMapping
2.3 خوارزمية المقارنة -> getMappingComparator
2.4 الكتابة فوق HandleMatch و Cache n معلومات متعددة لطلبها
تسجيل نمط ، أفضل نمط مطابقة ، معلمات محسورة في عنوان URL ، معلمات متعددة القيمة محفورة في عنوان URL ، MediaType
2.1.5 الكتابة فوق المعالجة ، حاول أن تطابقها مرة أخرى بعد الصراع الأخير
3. requestMappingHandLermapping إنشاء requestMappingInfo وفقًا للشرح التعويضي controller @requestmapping والتحقق من isHandler
3.1 الكتابة فوق pretpropertiesset وأضف لاحقة الملف للحكم
3.2 تنفيذ Ishandler ، وأحد التعليقات التوضيحية على الفصل صحيحة.
3.3 تحليل محتوى التعليقات التوضيحية وإنتاج مثيلات requestMappingInfo