השוואת AOP האביב ו- AspectJ

1. הקדמה

ישנן מספר ספריות AOP זמינות כיום, ואלה צריכות להיות מסוגלות לענות על מספר שאלות:

  • האם זה תואם ליישום הקיים או החדש שלי?
  • היכן אוכל ליישם AOP?
  • כמה מהר זה ישתלב עם היישום שלי?
  • מה התקורה של הביצועים?

במאמר זה נבחן מענה לשאלות אלו ונציג את Spring AOP ו- AspectJ - שתי מסגרות ה- AOP הפופולריות ביותר עבור Java.

2. מושגי AOP

לפני שנתחיל, בוא נעשה סקירה מהירה ורמה גבוהה של מונחים ומושגי ליבה:

  • היבט - קוד / תכונה סטנדרטית המפוזרת על פני מספר מקומות ביישום ושונה בדרך כלל מההיגיון העסקי בפועל (למשל, ניהול עסקאות). כל היבט מתמקד בפונקציונליות רוחבית ספציפית
  • נקודת ציון - זו נקודה מסוימת במהלך ביצוע תוכניות כמו ביצוע שיטה, שיחת בנאי או הקצאת שטח
  • עצה - הפעולה שביצע ההיבט בנקודת צירוף ספציפית
  • Pointcut - ביטוי רגולרי התואם לנקודת צירוף. בכל פעם שנקודת צירוף כלשהי תואמת לקיצור דרך, מתבצעת ייעוץ מוגדר המשויך לאותו קיצור
  • אריגה - תהליך קישור היבטים לאובייקטים ממוקדים ליצירת אובייקט מומלץ

3. אביב AOP ו- AspectJ

עכשיו, בואו נדון באביב AOP ו- AspectJ על פני מספר צירים - כגון יכולות, יעדים, אריגה, מבנה פנימי, נקודות צירוף ופשטות.

3.1. יכולות ויעדים

במילים פשוטות, לאביב AOP ו- AspectJ יש מטרות שונות.

Spring AOP שואף לספק יישום פשוט של AOP ברחבי ה- IoC של Spring כדי לפתור את הבעיות הנפוצות ביותר שעומדות בפני מתכנתים. זה לא נועד כפתרון AOP מלא - ניתן למרוח אותו רק על שעועית המנוהלת על ידי מיכל אביב.

מצד שני, AspectJ היא טכנולוגיית AOP המקורית שמטרתה לספק פתרון AOP מלא. זה חזק יותר אבל גם מסובך יותר באופן משמעותי מאשר AOP באביב. ראוי גם לציין שניתן ליישם את AspectJ בכל אובייקטים בתחום.

3.2. אֲרִיגָה

גם AspectJ וגם Spring AOP משתמשים בסוג השזירה השונה אשר משפיע על התנהגותם ביחס לביצועים וקלות השימוש.

AspectJ עושה שימוש בשלושה סוגים שונים של אריגה:

  1. אריגה בזמן הידור: המהדר של AspectJ לוקח כקלט גם את קוד המקור של ההיבט שלנו וגם את היישום שלנו ומייצר קבצי מחלקה ארוגים כפלט
  2. אריגה לאחר הידור: זה ידוע גם בשם אריגה בינארית. הוא משמש לשזירת קבצי מחלקה וקבצי JAR קיימים עם ההיבטים שלנו
  3. אריגה בזמן העמסה: זה בדיוק כמו האריגה הבינארית לשעבר, עם ההבדל כי האריגה נדחית עד שמעמיס מחלקה יטען את קבצי הכיתה ל- JVM

למידע מעמיק יותר על AspectJ עצמה, עבור למאמר זה.

מכיוון ש- AspectJ משתמש באריגת זמן קומפילציה ואריגת זמן בכיתה, אביב AOP עושה שימוש באריגה בזמן ריצה.

עם אריגת זמן ריצה, ההיבטים נשזרים במהלך ביצוע היישום באמצעות פרוקסי של האובייקט הממוקד - תוך שימוש ב- Proxy דינמי JDK או ב- proxy CGLIB (עליהם נדון בנקודה הבאה):

3.3. מבנה פנימי ויישום

אביב AOP הוא מסגרת AOP מבוססת פרוקסי. המשמעות היא שכדי ליישם היבטים לאובייקטים היעדיים, היא תיצור פרוקסי של אובייקט זה. זה מושג באחת משתי הדרכים:

  1. פרוקסי דינמי של JDK - הדרך המועדפת על AOP באביב. בכל פעם שהאובייקט הממוקד מיישם אפילו ממשק אחד, אז ישמש proxy דינמי של JDK
  2. פרוקסי CGLIB - אם אובייקט היעד אינו מיישם ממשק, ניתן להשתמש ב- proxy CGLIB

אנו יכולים ללמוד עוד על מנגנוני Proxying באביב AOP מהמסמכים הרשמיים.

לעומת זאת, AspectJ לא עושה דבר בזמן הריצה מכיוון שהשיעורים נערכים ישירות עם היבטים.

וכך בניגוד ל- Spring AOP, זה לא דורש שום דפוסי עיצוב. כדי לשזור את ההיבטים לקוד, הוא מציג את המהדר שלו המכונה מהדר AspectJ (ajc), דרכו אנו מחברים את התוכנית שלנו ואז מריץ אותה על ידי אספקת ספריית זמן ריצה קטנה (<100K).

3.4. נקודות הצטרפות

בסעיף 3.3 הראינו כי AOP של אביב מבוסס על דפוסי פרוקסי. מסיבה זו, היא צריכה לסווג את מחלקת ה- Java הממוקדת ולהחיל על כך חששות רוחביים.

אבל זה בא עם מגבלה. איננו יכולים ליישם חששות (או היבטים) רוחביים על פני כיתות שהן "סופיות" מכיוון שלא ניתן לעקוף אותם ולכן זה יביא לחריג בזמן ריצה.

כנ"ל לגבי שיטות סטטיות וסופיות. לא ניתן להחיל עליהם היבטים אביביים מכיוון שלא ניתן לעקוף אותם. מכאן ש- Spring AOP בגלל מגבלות אלה, תומך רק בנקודות הצטרפות לביצוע שיטות.

למרות זאת, AspectJ שוזר את החששות הרוחביים ישירות לתוך הקוד בפועל לפני זמן הריצה. שלא כמו Spring AOP, זה לא דורש לסווג מחדש את האובייקט הממוקד ובכך תומך גם בנקודות צירוף רבות אחרות. להלן סיכום נקודות הצטרפות הנתמכות:

נקודת הצטרפותאביב AOP נתמךAspectJ נתמך
שיטת שיחהלאכן
ביצוע שיטהכןכן
שיחת קונסטרוקטורלאכן
ביצוע קונסטרוקטורלאכן
ביצוע אתחול סטטילאכן
אתחול אובייקטלאכן
התייחסות לשטחלאכן
מטלה בשטחלאכן
ביצוע מטפללאכן
ביצוע ייעוץלאכן

ראוי גם לציין כי באביב AOP, היבטים אינם מיושמים על השיטה הנקראת באותה כיתה.

זה כמובן מכיוון שכאשר אנו קוראים לשיטה באותו מחלקה, אנו לא קוראים לשיטת ה- proxy שמספק Spring AOP. אם אנו זקוקים לפונקציונליות זו, עלינו להגדיר שיטה נפרדת בשעועית שונה, או להשתמש ב- AspectJ.

3.5. פַּשְׁטוּת

AOP של אביב ברור יותר מכיוון שהוא אינו מציג שום מהדר או אורג נוסף בין תהליך הבנייה שלנו. הוא משתמש באריגת זמן ריצה, ולכן הוא משתלב בצורה חלקה עם תהליך הבנייה הרגיל שלנו. למרות שזה נראה פשוט, זה עובד רק עם שעועית שמנוהלת על ידי אביב.

עם זאת, כדי להשתמש ב- AspectJ, אנו נדרשים להציג את המהדר AspectJ (ajc) ולארוז מחדש את כל הספריות שלנו (אלא אם כן נעבור לאריגה שלאחר הידור או זמן טעינה).

זה, כמובן, מסובך יותר מהראשון - מכיוון שהוא מציג את AspectJ Java Tools (הכוללים מהדר (ajc), ניפוי באגים (ajdb), מחולל תיעוד (ajdoc), דפדפן מבנה תוכנית (ajbrowser)) שאנו צריך להשתלב עם ה- IDE שלנו או עם כלי הבנייה.

3.6. ביצועים

מבחינת ביצועים, אריגת זמן הידור מהירה בהרבה מאריגת זמן ריצה. אביב AOP הוא מסגרת מבוססת פרוקסי, ולכן יש יצירת פרוקסי Proxy בזמן הפעלת היישום. כמו כן, ישנן כמה קריאות שיטה נוספות לכל היבט, המשפיעות על הביצועים באופן שלילי.

מצד שני, AspectJ שוזר את ההיבטים בקוד הראשי לפני ביצוע היישום ולכן אין תקורה נוספת של זמן ריצה, בניגוד ל- Spring AOP.

מסיבות אלה, המדדים מציעים ש- AspectJ מהיר כמעט פי 8 עד 35 מ- AOP באביב.

4. סיכום

טבלה מהירה זו מסכמת את ההבדלים העיקריים בין AOP האביב ל- AspectJ:

אביב AOPהיבט
מיושם בג'אווה טהורהמיושם באמצעות הרחבות של שפת התכנות Java
אין צורך בתהליך הידור נפרדזקוק למהדר AspectJ (ajc) אלא אם כן מוגדר LTW
רק אריגה בזמן ריצה זמינהאריגת זמן ריצה אינה זמינה. תומך באריגת זמן הידור, פוסט-קומפילציה וזמן טעינה
פחות עוצמתי - תומך רק באריגה ברמת השיטהעוצמתי יותר - יכול לשזור שדות, שיטות, בונים, אתחול סטטי, מחלקה / שיטות סופיות וכו '...
ניתן ליישם רק על שעועית המנוהלת על ידי מיכל אביבניתן ליישום בכל אובייקטי התחום
תומך רק בקיצורי דרך לביצוע שיטותתמוך בכל קיצורי הדרך
פרוקסי ייצור נוצרים מאובייקטים ממוקדים, והיבטים מוחלים על פרוקסי אלההיבטים נשזרים ישירות בקוד לפני ביצוע היישום (לפני זמן ריצה)
הרבה יותר איטי מ- AspectJהופעה יותר טובה
קל ללמוד וליישםיחסית מורכב יותר מ- AOP באביב

5. בחירת המסגרת הנכונה

אם ננתח את כל הטיעונים המובאים בסעיף זה, נתחיל להבין שבכלל לא מסגרת אחת טובה יותר מאחרת.

במילים פשוטות, הבחירה תלויה במידה רבה בדרישות שלנו:

  • מסגרת: אם היישום אינו משתמש במסגרת Spring, אין לנו אפשרות אלא להפיל את הרעיון להשתמש ב- Spring AOP מכיוון שהיא אינה יכולה לנהל דבר שאינו נמצא בהישג יד של מיכל האביב. עם זאת, אם היישום שלנו נוצר לחלוטין באמצעות Spring Spring, אנו יכולים להשתמש ב- Spring AOP מכיוון שהוא פשוט ללמוד וליישם
  • גמישות: בהינתן התמיכה המוגבלת בנקודות הצטרפות, Spring AOP אינו פיתרון AOP מלא, אך הוא פותר את הבעיות הנפוצות ביותר שעומדות בפני מתכנתים. אם כי אם אנו רוצים להעמיק ולנצל את AOP ליכולתו המקסימלית ונרצה את התמיכה ממגוון רחב של נקודות צירוף זמינות, אז AspectJ היא הבחירה.
  • ביצועים: אם אנו משתמשים בהיבטים מוגבלים, יש הבדלים בביצועים טריוויאליים. אך לעיתים ישנם מקרים בהם ליישום יש יותר מעשרות אלפי היבטים. לא נרצה להשתמש באריגת זמן ריצה במקרים כאלה ולכן עדיף לבחור ב- AspectJ. ידוע ש- AspectJ מהיר פי 8 עד 35 מ- AOP באביב
  • הטוב משניהם: שתי המסגרות הללו תואמות זו את זו באופן מלא. אנחנו תמיד יכולים לנצל את AOP האביב במידת האפשר ועדיין להשתמש ב- AspectJ כדי לקבל תמיכה בנקודות צירוף שאינן נתמכות על ידי לשעבר

6. מסקנה

במאמר זה ניתחנו את האביב AOP ו- AspectJ, בכמה תחומי מפתח.

השווינו בין שתי הגישות ל- AOP הן בנוגע לגמישות והן באיזו קלות הן יתאימו ליישום שלנו.


$config[zx-auto] not found$config[zx-overlay] not found