moji5
کاربر فعال كامپيوتر و اينترنت
دو اصطلاح Tangling و Scattering
● پراكندگي: (Scattering) پيادهسازي يك Concern، پراكنده شده است هر گاه كد آن بين چند ماجول پخش شده باشد.
● پيچش: (Tangling) پيادهسازي يك Concern، پيچيده شدهاست هر گاه كد آن با كد يك Concern ديگر مخلوط شده باشد.
پراكندگي و پيچش در Aspect Oriented بهعنوان علائم يك Cross-Cutting Concern در نظر گرفته ميشوند. در حقيقت عموماً Concernهايي كه چنين خصوصياتي را در پيادهسازيهاي غير AOP داشته باشند، مورد بحث قرار ميگيرند.
AOP در عمل
بايد اعتراف كرد كه با وجود ارزشمند بودن توضيحات و تئوريهاي برنامهنويسي، تا وقتي كه آنها را در عمل، به وسيله برنامهنويسي مورد آزمايش قرار ندهيم، در حقيقت كار خاصي انجام ندادهايم. در ادامه سعي ميكنيم مفاهيم مطرح شده را به همراه كد آن مورد بررسي قرار دهيم تا علاوه بر معرفي و تعريف مفاهيم موجود در AOP، با نحوه به كارگيري آنان نيز آشنا شويم، اما قبل از هر چيز بايد به اين سؤال پاسخ دهيم كه كجا ميتوانيم AOPبنويسيم؟
براي پاسخ دادن به اين پرسش، ابتدا بايد ببينيد AOP چگونه اجرا ميشود. براي نوشتن يك پروژه به صورت AOPشما ابتدا هر دو بخش كد خود را (اعم از روند كاري اصلي برنامه و كدهاي مربوط به Aspectها) به صورت جداگانه در يك زبان شيءگرا مينويسيد و سپس موجودي به نام Aspect Weaver آن دو بخش را با يكديگر تركيب كرده و كد نهايي را ميسازد.
جداسازي كد اصلي و كد Concernها (كد اصلي نيازي به اطلاع از بخش Concernها ندارد) به افزايش قابليت استفاده دوباره (Reusability) و قابليت نگهداري (Maintainability) پروژه كمك شاياني ميكند. شكل 1 نحوه كار Weaverها را نشان ميدهد.
دو نمونه بارز از ابزارهايي كه ميتوان با استفاده از آنها برنامههاي Aspect-Oriented نوشت AspectJ و AspectWerkz هستند.
AspectJ يك Extension است كه براي زبان جاوا در زيراكس پارك و توسط گروه بهوجود آورنده AOP نوشته شدهاست. اين Extension به دو صورت تنها و تعبيه شده در Eclipse IDE عرضه ميشود. AspectJ پتانسيل پشتيباني از مدلRT Weaver را نيزدارد، اما براي بهره بردن از تواناييهاي آن بايد از آن بهصورت يك Compile-time Weaver استفاده كرد (هماكنون به صورت Compile-time و loadtime عرضه ميشود).
● پراكندگي: (Scattering) پيادهسازي يك Concern، پراكنده شده است هر گاه كد آن بين چند ماجول پخش شده باشد.
● پيچش: (Tangling) پيادهسازي يك Concern، پيچيده شدهاست هر گاه كد آن با كد يك Concern ديگر مخلوط شده باشد.
پراكندگي و پيچش در Aspect Oriented بهعنوان علائم يك Cross-Cutting Concern در نظر گرفته ميشوند. در حقيقت عموماً Concernهايي كه چنين خصوصياتي را در پيادهسازيهاي غير AOP داشته باشند، مورد بحث قرار ميگيرند.
AOP در عمل
بايد اعتراف كرد كه با وجود ارزشمند بودن توضيحات و تئوريهاي برنامهنويسي، تا وقتي كه آنها را در عمل، به وسيله برنامهنويسي مورد آزمايش قرار ندهيم، در حقيقت كار خاصي انجام ندادهايم. در ادامه سعي ميكنيم مفاهيم مطرح شده را به همراه كد آن مورد بررسي قرار دهيم تا علاوه بر معرفي و تعريف مفاهيم موجود در AOP، با نحوه به كارگيري آنان نيز آشنا شويم، اما قبل از هر چيز بايد به اين سؤال پاسخ دهيم كه كجا ميتوانيم AOPبنويسيم؟
براي پاسخ دادن به اين پرسش، ابتدا بايد ببينيد AOP چگونه اجرا ميشود. براي نوشتن يك پروژه به صورت AOPشما ابتدا هر دو بخش كد خود را (اعم از روند كاري اصلي برنامه و كدهاي مربوط به Aspectها) به صورت جداگانه در يك زبان شيءگرا مينويسيد و سپس موجودي به نام Aspect Weaver آن دو بخش را با يكديگر تركيب كرده و كد نهايي را ميسازد.
جداسازي كد اصلي و كد Concernها (كد اصلي نيازي به اطلاع از بخش Concernها ندارد) به افزايش قابليت استفاده دوباره (Reusability) و قابليت نگهداري (Maintainability) پروژه كمك شاياني ميكند. شكل 1 نحوه كار Weaverها را نشان ميدهد.
دو نمونه بارز از ابزارهايي كه ميتوان با استفاده از آنها برنامههاي Aspect-Oriented نوشت AspectJ و AspectWerkz هستند.
AspectJ يك Extension است كه براي زبان جاوا در زيراكس پارك و توسط گروه بهوجود آورنده AOP نوشته شدهاست. اين Extension به دو صورت تنها و تعبيه شده در Eclipse IDE عرضه ميشود. AspectJ پتانسيل پشتيباني از مدلRT Weaver را نيزدارد، اما براي بهره بردن از تواناييهاي آن بايد از آن بهصورت يك Compile-time Weaver استفاده كرد (هماكنون به صورت Compile-time و loadtime عرضه ميشود).
Aspect Weaver !
در حقيقت Aspect Weaver كد اصلي و كد Aspectها را بهعنوان ورودي ميگيرد و محصول نهايي را توليد ميكند. توجه به اين موضوع ضروري است كه نگاه كلي به Weaverها مانند يك كامپايلر نيست، زيرا قرار نيست كه تمام كارهاي پيچيدهاي را كه يك كامپايلر انجام ميدهد.
Weaver نيز در مورد تركيب دو بخش كد انجام دهد. در حقيقت، همانطور كه خود كيزالس هم اشاره مي كند، وظيفه Weaverها فقط Integration (مجتمعسازي) است.
تكنيكهاي اوليه Weaving به دو دسته عمده تقسيم ميشوند: Compile Time) CT) و Run-Time) RT Weaver)هايCT. همانطور كه از نامشان پيدا است، تمام كارهاي مربوط به تركيب كد را در زمان كامپايل انجام ميدهند و در حقيقت كد نهايي كه اجرا ميشود، محصول كامل است.
در مقابل RTها اينكار را در زمان اجرا انجام ميدهند و ايجاد ارتباط را تا آن وقت به تأخير مياندازند. Weaverهاي CT با توجه به اين كه تمام فرآيند ايجاد ارتباط را در ابتداي كار و هنگام كامپايل انجام ميدهند بسيار سريعتر از RTها عمل ميكنند، اما در مقابل RTها هم اين مزيت را دارند كه در صورت تغيير كد Aspectها نيازي به انجام دوباره عمليات Weaving نيست و برخلاف CTها در Run-Time Weaver تغييرات در كد بدون نياز به هيچ كاري سريع منعكس ميشوند.
همانطور كه در بالا ذكر كرديم، تكنيكهاي Weaving ديگري نيز وجود دارند كه در واقع فضاي بين Compile-time و Run-time قرار ميگيرند. اين دو تكنيك Weaving را (post-compile time (binary و Load-time مينامند.
Binary Weaving در حقيقت عمليات Weaving را روي byte code انجام ميدهد (پس از كامپايل). Load time Weaving نيز يك نوع binary Weaving است. با اين تفاوت كه عمليات Weaving را تا زماني كه يك كلاس به Class loader معرفي نشده است، به تأخير مياندازد.
(اين توانايي ميتواند برخي از نقصهاي مدل Compile-time را برطرف كند، زيرا شما ميتوانيد بدون كامپايل كردن دوباره كد اصلي خود (Aspect ،(Business Logicهايي به برنامه اضافه كرده و سپس آنها را به پروژه اصلي لينك دهيد). در حقيقت، در اين مدل تا جايي كه ممكن است عمليات Weaving به تأخير ميافتد و تا مرحله Load شدن كلاسهاي موردنياز هيچ تركيبي انجام نميشود.
AspectJ محيطي ساده و بسيار كارا دارد و هماكنون محبوبترين ابزار برنامهنويسي Aspect-Oriented است. نسخههاي جديدتر AspectJ بهطور كامل با محيط توسعه Eclipse هماهنگي دارند و ميتوان از تمام امكانات Eclipse در مورد Aspectها نيز سود برد.
توجه به اين نكته ضروري است كه AspectJ تغييراتي در Syntax زبان به وجود ميآورد كه اين موضوع ميتواند باعث بروز مشكلاتي شود (Eclipse با توجه به اضافه كردن Keywordهاي مربوط به برنامهنويسي AOP اين مشكل را ندارد).
اين مشكلات باعث شدند تا ابزارهاي ديگري به وجود آيند كه به اين تغييرات گرامري در زبان برنامهنويسي نيازي نداشته باشند. يك نمونه مشهور از اين زبانها AspectWerkz است. AspectWerkz در حال حاضر از هر سه مدل Compile-time ،Load-time و Run time استفاده ميكند.
خصوصيت بارز AspectWerkz اين است كه Syntax زبان را تغيير نميدهد و در حقيقت تغييرات را با استفاده از Annotation انجام ميدهد كه به يك ساختار زباني جديد نيازي ندارد.
در حال حاضر، دو پروژه AspectJ و AspectWerkz با يكديگر تركيب شدهاند تا بتوانيم از قابليتهاي هر دو به صورت همزمان استفاده كنيم.
تمام اين مقدمهها براي اين ذكر شد كه شما كمي بيشتر با نحوه عملكرد داخلي ابزارهاي توسعه برنامههاي Aspect-Oriented آشنا شويد. در قسمت بعد وارد بخش كدنويسي ميشويم.
در حقيقت Aspect Weaver كد اصلي و كد Aspectها را بهعنوان ورودي ميگيرد و محصول نهايي را توليد ميكند. توجه به اين موضوع ضروري است كه نگاه كلي به Weaverها مانند يك كامپايلر نيست، زيرا قرار نيست كه تمام كارهاي پيچيدهاي را كه يك كامپايلر انجام ميدهد.
Weaver نيز در مورد تركيب دو بخش كد انجام دهد. در حقيقت، همانطور كه خود كيزالس هم اشاره مي كند، وظيفه Weaverها فقط Integration (مجتمعسازي) است.
تكنيكهاي اوليه Weaving به دو دسته عمده تقسيم ميشوند: Compile Time) CT) و Run-Time) RT Weaver)هايCT. همانطور كه از نامشان پيدا است، تمام كارهاي مربوط به تركيب كد را در زمان كامپايل انجام ميدهند و در حقيقت كد نهايي كه اجرا ميشود، محصول كامل است.
در مقابل RTها اينكار را در زمان اجرا انجام ميدهند و ايجاد ارتباط را تا آن وقت به تأخير مياندازند. Weaverهاي CT با توجه به اين كه تمام فرآيند ايجاد ارتباط را در ابتداي كار و هنگام كامپايل انجام ميدهند بسيار سريعتر از RTها عمل ميكنند، اما در مقابل RTها هم اين مزيت را دارند كه در صورت تغيير كد Aspectها نيازي به انجام دوباره عمليات Weaving نيست و برخلاف CTها در Run-Time Weaver تغييرات در كد بدون نياز به هيچ كاري سريع منعكس ميشوند.
همانطور كه در بالا ذكر كرديم، تكنيكهاي Weaving ديگري نيز وجود دارند كه در واقع فضاي بين Compile-time و Run-time قرار ميگيرند. اين دو تكنيك Weaving را (post-compile time (binary و Load-time مينامند.
Binary Weaving در حقيقت عمليات Weaving را روي byte code انجام ميدهد (پس از كامپايل). Load time Weaving نيز يك نوع binary Weaving است. با اين تفاوت كه عمليات Weaving را تا زماني كه يك كلاس به Class loader معرفي نشده است، به تأخير مياندازد.
(اين توانايي ميتواند برخي از نقصهاي مدل Compile-time را برطرف كند، زيرا شما ميتوانيد بدون كامپايل كردن دوباره كد اصلي خود (Aspect ،(Business Logicهايي به برنامه اضافه كرده و سپس آنها را به پروژه اصلي لينك دهيد). در حقيقت، در اين مدل تا جايي كه ممكن است عمليات Weaving به تأخير ميافتد و تا مرحله Load شدن كلاسهاي موردنياز هيچ تركيبي انجام نميشود.
AspectJ محيطي ساده و بسيار كارا دارد و هماكنون محبوبترين ابزار برنامهنويسي Aspect-Oriented است. نسخههاي جديدتر AspectJ بهطور كامل با محيط توسعه Eclipse هماهنگي دارند و ميتوان از تمام امكانات Eclipse در مورد Aspectها نيز سود برد.
توجه به اين نكته ضروري است كه AspectJ تغييراتي در Syntax زبان به وجود ميآورد كه اين موضوع ميتواند باعث بروز مشكلاتي شود (Eclipse با توجه به اضافه كردن Keywordهاي مربوط به برنامهنويسي AOP اين مشكل را ندارد).
اين مشكلات باعث شدند تا ابزارهاي ديگري به وجود آيند كه به اين تغييرات گرامري در زبان برنامهنويسي نيازي نداشته باشند. يك نمونه مشهور از اين زبانها AspectWerkz است. AspectWerkz در حال حاضر از هر سه مدل Compile-time ،Load-time و Run time استفاده ميكند.
خصوصيت بارز AspectWerkz اين است كه Syntax زبان را تغيير نميدهد و در حقيقت تغييرات را با استفاده از Annotation انجام ميدهد كه به يك ساختار زباني جديد نيازي ندارد.
در حال حاضر، دو پروژه AspectJ و AspectWerkz با يكديگر تركيب شدهاند تا بتوانيم از قابليتهاي هر دو به صورت همزمان استفاده كنيم.
تمام اين مقدمهها براي اين ذكر شد كه شما كمي بيشتر با نحوه عملكرد داخلي ابزارهاي توسعه برنامههاي Aspect-Oriented آشنا شويد. در قسمت بعد وارد بخش كدنويسي ميشويم.
كدنويسي در AspectJ
در اين قسمت به بررسي پيادهسازي مفاهيم مختلف AOP توسط AspectJ ميپردازيم. هر چند بررسي تمام خصوصيات AspectJ خود يك مقاله جداگانه ميطلبد، اما سعي ميكنيم تا مفاهيم اصلي پركاربرد را در نوشتن يك برنامه Aspect-Oriented مطرح كنيم. در شمارههاي آينده، بهطور عميقتري به بررسي جنبههاي عملي AOPميپردازيم.
در اين قسمت به بررسي پيادهسازي مفاهيم مختلف AOP توسط AspectJ ميپردازيم. هر چند بررسي تمام خصوصيات AspectJ خود يك مقاله جداگانه ميطلبد، اما سعي ميكنيم تا مفاهيم اصلي پركاربرد را در نوشتن يك برنامه Aspect-Oriented مطرح كنيم. در شمارههاي آينده، بهطور عميقتري به بررسي جنبههاي عملي AOPميپردازيم.

Annotation
شايد تعريف كردن Annotation كمي دشوار باشد. در حقيقت آنها برچسبها و شايد پايگاهدادههايي هستند كه اطلاعاتي درباره برنامه شما ميدهند.
در حقيقت، Annotationها تغييري در Semantic زبان ايجاد نميكنند، اما ميتوانند براي ابزارهاي مختلفي كه در روند اجراي برنامه دخيل هستند، پيغامهايي در برداشته باشند.
در حقيقت، ميتوان Annotationها را علامتهايي تلقي كرد كه كامپايلر آنها را بهعنوان متاديتا در جايي ذخيره ميكند. سپس VM (سرنام Virtual Machine) با ديدن آنها تعيين ميكند كه چگونه رفتار بعضي از Elementهاي برنامه را تغيير دهد.
توضيح كامل Annotationها در اين مقاله نميگنجد. پس به ذكر همين مقدمات بسنده ميكنيم.
شايد تعريف كردن Annotation كمي دشوار باشد. در حقيقت آنها برچسبها و شايد پايگاهدادههايي هستند كه اطلاعاتي درباره برنامه شما ميدهند.
در حقيقت، Annotationها تغييري در Semantic زبان ايجاد نميكنند، اما ميتوانند براي ابزارهاي مختلفي كه در روند اجراي برنامه دخيل هستند، پيغامهايي در برداشته باشند.
در حقيقت، ميتوان Annotationها را علامتهايي تلقي كرد كه كامپايلر آنها را بهعنوان متاديتا در جايي ذخيره ميكند. سپس VM (سرنام Virtual Machine) با ديدن آنها تعيين ميكند كه چگونه رفتار بعضي از Elementهاي برنامه را تغيير دهد.
توضيح كامل Annotationها در اين مقاله نميگنجد. پس به ذكر همين مقدمات بسنده ميكنيم.
Join Point
Join Point، در حقيقت مفهوم جديدي نيست. ما از اين مفهوم قبلاً بارها استفاده كردهايم ، فقط شايد اسمي براي آن نداشتهايمJoint Point .ها نقاط خوش تعريف خاصي در برنامه هستند. بهعنوان مثال، نقطه فراخواني يا بازگشت متد.
Aspect
شروع كاري ما براي آوردن AOP به صحنه عمل كليدواژه Aspect است. Aspectها تقريباً مشابه كليدواژه class در نوشتن كدهاي معمولي شيءگرا هستند. هر Aspect بايد در يك فايل جداگانه كه نام آن با نام Aspect يكي است، تعريف شود:
Join Point، در حقيقت مفهوم جديدي نيست. ما از اين مفهوم قبلاً بارها استفاده كردهايم ، فقط شايد اسمي براي آن نداشتهايمJoint Point .ها نقاط خوش تعريف خاصي در برنامه هستند. بهعنوان مثال، نقطه فراخواني يا بازگشت متد.
Aspect
شروع كاري ما براي آوردن AOP به صحنه عمل كليدواژه Aspect است. Aspectها تقريباً مشابه كليدواژه class در نوشتن كدهاي معمولي شيءگرا هستند. هر Aspect بايد در يك فايل جداگانه كه نام آن با نام Aspect يكي است، تعريف شود:

يك Aspect مجموعهاي از point-cutها و Adviceها است.
Point-cut
در AOP شما نياز داريد نقاط خاصي را بهعنوان نقاطي كه موجب فراخواني يك Aspect ميشوند، تعريف كنيد. اين كار توسط Point-cutها انجام ميگيرد. در حقيقت، Point-cutها يك مجموعه از Join Pointها را تعريف ميكنند و ميتوانيم آنها را بهعنوان يك Query براي انتخاب joint pointها در نظر بگيريم.
در حقيقت، تعريف يك point-cut بيانكننده اين موضوع است كه join Pointهاي كد اصلي (Business Logic) در چه جاهايي قرار دارند. به زبان سادهتر point-cut شرايط نقطههايي را تعريف ميكند كه بايد با رسيدن به آنها در كد اصلي اين Aspect اجرا شود.
اين مكانيسم، به مكانيسم فراخواني روش بسيار شبيه است. در حقيقت، در اينجا point-cutها حكم يك روش و join point حكم نقطهاي است كه دستور فراخواني متد در آن قرار دارد.
به عنوان مثال:
Point-cut
در AOP شما نياز داريد نقاط خاصي را بهعنوان نقاطي كه موجب فراخواني يك Aspect ميشوند، تعريف كنيد. اين كار توسط Point-cutها انجام ميگيرد. در حقيقت، Point-cutها يك مجموعه از Join Pointها را تعريف ميكنند و ميتوانيم آنها را بهعنوان يك Query براي انتخاب joint pointها در نظر بگيريم.
در حقيقت، تعريف يك point-cut بيانكننده اين موضوع است كه join Pointهاي كد اصلي (Business Logic) در چه جاهايي قرار دارند. به زبان سادهتر point-cut شرايط نقطههايي را تعريف ميكند كه بايد با رسيدن به آنها در كد اصلي اين Aspect اجرا شود.
اين مكانيسم، به مكانيسم فراخواني روش بسيار شبيه است. در حقيقت، در اينجا point-cutها حكم يك روش و join point حكم نقطهاي است كه دستور فراخواني متد در آن قرار دارد.
به عنوان مثال:

اين Pointcut مشخص ميكند كه پس از اجراي متد از كلاس Data كه با Write شروع ميشوند و هيچ ورودياي ندارند، اين Aspect فراخواني ميشود.
ميتوانيم در يك Aspect چند pointcut داشته باشيم. كد پايين سه pointcut تعريف ميكند.
ميتوانيم در يك Aspect چند pointcut داشته باشيم. كد پايين سه pointcut تعريف ميكند.

در كد بالا سه pointcut تعريف شده است.
PC1: وقتي متدي از كلاس Data كه با Write شروع ميشود و آرگومان String ميگيرد، فراخواني ميشود، pointcut PC1 رخ ميدهد.
PC2: با فراخواني هر متدي (هر نامي با هر ورودياي) كه در داخل كلاس Data است pointcut PC2 رخ ميدهد.
PC3: با اجراي بدنه اصلي متد SecurityChecking ،pointcut PC3 فراخواني ميشود.
Advice
كد تكميلي كه به سيستم اضافه ميشود تا كارهاي مربوط به يك Concern را انجام دهد، Advice نام دارد. Adviceها در حقيقت همان قطعهكدهاي معمولي هستند كه حكم انجام عملياتي يك Concern را دارند.
هر Advice كاري را كه يك Aspect بايد در ازاي وقوع يك اتفاق خاص (pointcut) انجام دهد، مشخص مي كند. باز هم با تعبير متدگونه advice در واقع حكم بدنه متد را دارد (point-cut حكم اعلان متد را دارد).
كاري كه كد زير انجام ميدهد اين است كه قبل از اجراي هر متدي از كلاس Data كه با Write شروع ميشود و هيچ ورودي ندارد، هويت كاربر حال حاضر بررسي ميشود.
PC1: وقتي متدي از كلاس Data كه با Write شروع ميشود و آرگومان String ميگيرد، فراخواني ميشود، pointcut PC1 رخ ميدهد.
PC2: با فراخواني هر متدي (هر نامي با هر ورودياي) كه در داخل كلاس Data است pointcut PC2 رخ ميدهد.
PC3: با اجراي بدنه اصلي متد SecurityChecking ،pointcut PC3 فراخواني ميشود.
Advice
كد تكميلي كه به سيستم اضافه ميشود تا كارهاي مربوط به يك Concern را انجام دهد، Advice نام دارد. Adviceها در حقيقت همان قطعهكدهاي معمولي هستند كه حكم انجام عملياتي يك Concern را دارند.
هر Advice كاري را كه يك Aspect بايد در ازاي وقوع يك اتفاق خاص (pointcut) انجام دهد، مشخص مي كند. باز هم با تعبير متدگونه advice در واقع حكم بدنه متد را دارد (point-cut حكم اعلان متد را دارد).
كاري كه كد زير انجام ميدهد اين است كه قبل از اجراي هر متدي از كلاس Data كه با Write شروع ميشود و هيچ ورودي ندارد، هويت كاربر حال حاضر بررسي ميشود.

Adviceها به سه نوع تقسيم ميشوند:
1-Before: اين Adviceها بلافاصله بعد از اينكه يك join point اتفاق افتاد و پيش از اين كه برنامه ادامه يابد اجرا ميشوند. بهعنوان مثال، اگر join point فراخواني يك ljn باشد، بلافاصله پس از فراخواني ljn (و پيش از اجراي بدنه آن و برگرداندن يك مقدار)، قطعه كد Advice اجرا ميشود.
2- After: اين نوع Advice نيز همانطور كه از نامش پيدا است، درست برخلاف Before عمل ميكند. Adviceهاي نوع After پس از پايان اجراي join point، اجرا ميشوند. در حقيقت، در مثال بالا (فراخواني متد) يك Advice از اين دسته پس از پايان روند كاري متد (برگرداندن مقدار- وقوع exception) اجرا ميشود.
3- Around: اين نوع بسيار جالب از Adviceها ميتوانند كلاً اجراي join point را ناديده بگيرند. در حقيقت Adviceهاي نوع Around دقيقاً به جاي join point اجرا ميشوند (اجراي join point ناديده گرفته ميشود و به جاي آن اين Advice اجرا ميشود). معني اين امر درباره متدها اين است كه بدنه اصلي متد اجرا نميشود و به جاي آن كد موجود در Advice اجرا ميشود.
يك كد تركيبي
كد زير تركيبي از سه pointcut و سه Advice را نشان ميدهد.
1-Before: اين Adviceها بلافاصله بعد از اينكه يك join point اتفاق افتاد و پيش از اين كه برنامه ادامه يابد اجرا ميشوند. بهعنوان مثال، اگر join point فراخواني يك ljn باشد، بلافاصله پس از فراخواني ljn (و پيش از اجراي بدنه آن و برگرداندن يك مقدار)، قطعه كد Advice اجرا ميشود.
2- After: اين نوع Advice نيز همانطور كه از نامش پيدا است، درست برخلاف Before عمل ميكند. Adviceهاي نوع After پس از پايان اجراي join point، اجرا ميشوند. در حقيقت، در مثال بالا (فراخواني متد) يك Advice از اين دسته پس از پايان روند كاري متد (برگرداندن مقدار- وقوع exception) اجرا ميشود.
3- Around: اين نوع بسيار جالب از Adviceها ميتوانند كلاً اجراي join point را ناديده بگيرند. در حقيقت Adviceهاي نوع Around دقيقاً به جاي join point اجرا ميشوند (اجراي join point ناديده گرفته ميشود و به جاي آن اين Advice اجرا ميشود). معني اين امر درباره متدها اين است كه بدنه اصلي متد اجرا نميشود و به جاي آن كد موجود در Advice اجرا ميشود.
يك كد تركيبي
كد زير تركيبي از سه pointcut و سه Advice را نشان ميدهد.

كد زير نيز كد كلاس Data است كه شامل روش main نيز است.

پس از كامپايل و اجراي Data خروجي زير را دريافت ميكنيم:

منبع : www.shabakeh-mag.com