חיווט באביב: @Autowired, @Resource ו- @ Inject

1. סקירה כללית

מאמר מסגרת האביב הזה ידגים את השימוש בהערות הקשורות להזרקת תלות, כלומר @מַשׁאָב, @לְהַזרִיק, ו @Autowired ביאורים. ביאורים אלה מספקים לשיעורים דרך הצהרתית לפתור תלות. לדוגמה:

@Autowired ArbitraryClass arbObject;

בניגוד לאינסטנטציה ישירה שלהם (הדרך הכרחית), למשל:

ArbitraryClass arbObject = ArbitraryClass חדש ();

שתיים משלוש ההערות שייכות לחבילת ההרחבה של Java: javax.annotation.Resource ו javax.inject.Inject. ה @Autowired ההערה שייכת ל org.springframework.beans.factory.annotation חֲבִילָה.

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

הדוגמאות יתמקדו כיצד להשתמש בשלוש הערות ההזרקה במהלך בדיקות האינטגרציה. התלות הנדרשת במבחן יכולה להיות קובץ שרירותי או מעמד שרירותי.

2. ה @מַשׁאָב אהערה

ה @מַשׁאָב ביאור הוא חלק מאוסף ההערות JSR-250 והוא ארוז עם ג'קרטה EE. להערה זו יש את נתיבי הביצוע הבאים, המפורטים לפי עדיפות:

  1. התאמה לפי שם
  2. התאמה לפי סוג
  3. התאמה לפי מוקדמות

נתיבי ביצוע אלה ישימים הן למגדיר ולהזרקת שדה.

2.1. הזרקת שדה

פתרון תלות על ידי הזרקת שדה מושג על ידי הערת משתנה מופע עם ה- @מַשׁאָב ביאור.

2.1.1. התאמה לפי שם

מבחן האינטגרציה המשמש להדגמת הזרקת שדה בהתאמה לפי שם מופיע כדלקמן:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, classes = ApplicationContextTestResourceNameType.class) מחלקה ציבורית שדה ברירת מחדל FieldResourceInjectionIntegrationTest {@Resource (name = "namedFile"); @Test הציבור בטל givenResourceAnnotation_WhenOnField_ThenDependencyValid () {assertNotNull (defaultFile); assertEquals ("namedFile.txt", defaultFile.getName ()); }}

בוא נעבור את הקוד. בתוך ה FieldResourceInjectionTest מבחן שילוב, בשורה 7, רזולוציית התלות לפי השם מושגת על ידי העברת שם השעועית כערך תכונה ל @מַשׁאָב ביאור:

@Resource (name = "namedFile") קובץ פרטי defaultFile;

תצורה זו תפתור תלות באמצעות נתיב ביצוע ההתאמה לפי שם. השעועית בשםFile חייב להיות מוגדר ב ApplicationContextTestResourceNameType הקשר יישום.

שים לב שמזהה השעועית וערך המאפיין המקביל חייבים להתאים:

@Configuration מחלקה ציבורית ApplicationContextTestResourceNameType {@Bean (name = "namedFile") קובץ ציבורי בשםFile () {קובץ בשםFile = קובץ חדש ("namedFile.txt"); החזר בשם File; }}

אי הגדרת השעועית בהקשר היישום תביא ל- org.springframework.beans.factory.NoSuchBeanDefinitionException נזרק. ניתן להדגים זאת על ידי שינוי ערך התכונה המועבר ל- @אפונה ביאור, ב ApplicationContextTestResourceNameType הקשר יישום; או שינוי ערך התכונה שהועבר ל- @מַשׁאָב ביאור, ב FieldResourceInjectionTest מבחן האינטגרציה.

2.1.2. התאמה לפי סוג

כדי להדגים את נתיב הביצוע לפי התאמה, פשוט הסר את ערך המאפיין בשורה 7 של ה- FieldResourceInjectionTest מבחן שילוב כך שייראה כך:

@Resource קובץ פרטי defaultFile;

ולהריץ את המבחן שוב.

המבחן עדיין יעבור כי אם @מַשׁאָב ביאור אינו מקבל שם שעועית כערך תכונה, מסגרת האביב תמשיך לרמה הבאה של עדיפות, התאמה לפי סוג, על מנת לנסות לפתור את התלות.

2.1.3. התאמה לפי מוקדמות

כדי להדגים את נתיב הביצוע בהתאמה לפי מוקדמות, תרחיש בדיקת האינטגרציה ישונה כך שמוגדרים שני שעועית ב ApplicationContextTestResourceQualifier הקשר יישום:

@Configuration מחלקה ציבורית ApplicationContextTestResourceQualifier {@Bean (name = "defaultFile") קובץ ציבורי defaultFile () {File defaultFile = קובץ חדש ("defaultFile.txt"); החזר defaultFile; } @Bean (name = "namedFile") קובץ ציבורי בשםFile () {File namedFile = קובץ חדש ("namedFile.txt"); החזר בשם File; }}

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

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, classes = ApplicationContextTestResourceQualifier.class) מחלקה ציבורית QualifierResourceInjectionIntegrationTest {@Resource תלות בקבצים פרטיים פרטיים; @ Resource פרטי תלות בקבצים 2; @Test הציבור בטל givenResourceAnnotation_WhenField_ThenDependency1Valid () {assertNotNull (תלות 1); assertEquals ("defaultFile.txt", dependency1.getName ()); } @Test ציבורי בטל givenResourceQualifier_WhenField_ThenDependency2Valid () {assertNotNull (תלות 2); assertEquals ("namedFile.txt", dependency2.getName ()); }}

הפעל את מבחן האינטגרציה ו- org.springframework.beans.factory.NoUniqueBeanDefinitionException נזרק. חריג זה נזרק מכיוון שהקשר היישום מצא שתי הגדרות שעועית מסוג קוֹבֶץ, וזה מבולבל לגבי איזה שעועית צריכה לפתור את התלות.

כדי לפתור בעיה זו, עיין בשורה 7 עד שורה 10 של ה- QualifierResourceInjectionTest מבחן האינטגרציה:

@Resource פרטי תלות בקבצים 1; @Resource פרטי תלות בקבצים 2;

והוסף את שורות הקוד הבאות:

@Qualifier ("defaultFile") @Qualifier ("namedFile")

כך שגוש הקוד ייראה כך:

@Resource @Qualifier ("defaultFile") תלות קבצים פרטית 1; @Resource @Qualifier ("בשםקובץ") תלות קבצים פרטית 2;

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

2.2. הזרקת סתר

מסלולי הביצוע שננקטו בעת הזרקת תלות בשדה חלים על הזרקה מבוססת מגדיר.

2.2.1. התאמה לפי שם

ההבדל היחיד הוא MethodResourceInjectionTest למבחן האינטגרציה יש שיטת מגדיר:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, classes = ApplicationContextTestResourceNameType.class) מחלקה ציבורית MethodResourceInjectionIntegrationTest {defaultFile של קובץ פרטי; @Resource (name = "namedFile") ריק מוגן setDefaultFile (קובץ defaultFile) {this.defaultFile = defaultFile; } @Test הריק ציבורי givenResourceAnnotation_WhenSetter_ThenDependencyValid () {assertNotNull (defaultFile); assertEquals ("namedFile.txt", defaultFile.getName ()); }}

פתרון תלות על ידי הזרקת סטר נעשה על ידי הערת שיטת הקביעה המתאימה של משתנה הפניה. העבר את שם תלות השעועית כערך תכונה ל- @מַשׁאָב ביאור:

פרטי קובץ defaultFile; @Resource (name = "namedFile") מוגן ריק setDefaultFile (קובץ defaultFile) {this.defaultFile = defaultFile; }

ה בשםFile נעשה שימוש חוזר בתלות שעועית בדוגמה זו. שם השעועית וערך המאפיין המתאים חייבים להתאים.

הפעל את מבחן האינטגרציה כמו שהוא והוא יעבור.

כדי לראות שהתלות אכן נפתרה על ידי נתיב הביצוע לפי התאמה לפי שם, שנה את ערך התכונה שהועבר ל @מַשׁאָב ביאור לערך על פי בחירתך והפעל את הבדיקה שוב. הפעם, המבחן ייכשל עם א NoSuchBeanDefinitionException.

2.2.2. התאמה לפי סוג

כדי להדגים ביצוע מבוסס התאמה, לפי התאמה לפי סוג, נשתמש ב- MethodByTypeResourceTest מבחן האינטגרציה:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, classes = ApplicationContextTestResourceNameType.class) מחלקה ציבורית MethodByTypeResourceIntegrationTest {defaultFile של קובץ פרטי; @Resource מוגן ריק setDefaultFile (קובץ defaultFile) {this.defaultFile = defaultFile; } @Test הציבור בטל givenResourceAnnotation_WhenSetter_ThenValidDependency () {assertNotNull (defaultFile); assertEquals ("namedFile.txt", defaultFile.getName ()); }}

הפעל את הבדיקה כמו שהיא, והיא תעבור.

על מנת לוודא שה- קוֹבֶץ התלות אכן נפתרה על ידי נתיב הביצוע בהתאמה לפי סוג, שנה את סוג הכיתה של ה- defaultFile משתנה לסוג מחלקה אחר כמו חוּט. בצע את MethodByTypeResourceTest מבחן אינטגרציה שוב והפעם א NoSuchBeanDefinitionException ייזרק.

החריג מאמת שהתאמה לפי סוג אכן שימשה לפתרון קוֹבֶץ תלות. ה NoSuchBeanDefinitionException מאשר ששם משתנה ההפניה אינו צריך להתאים לשם השעועית. במקום זאת, רזולוציית התלות תלויה בסוג המחלקה של שעועית התואם את סוג המחלקה של המשתנה.

2.2.3. התאמה לפי מוקדמות

ה MethodByQualifierResourceTest מבחן שילוב ישמש להדגמת מסלול הביצוע של התאמה אחר מזכה:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, classes = ApplicationContextTestResourceQualifier.class) מחלקה ציבורית MethodByQualifierResourceIntegrationTest {קובץ פרטי סמיכות תלות; קובץ פרטי AnotherArbDependency; @Test הציבור בטל givenResourceQualifier_WhenSetter_ThenValidDependencies () {assertNotNull (arbDependency); assertEquals ("namedFile.txt", arbDependency.getName ()); assertNotNull (AnotherArbDependency); assertEquals ("defaultFile.txt", anotherArbDependency.getName ()); } @Resource @Qualifier ("בשםקובץ") setArbDependency ציבורי ריק (קובץ arbDependency) {this.arbDependency = arbDependency; } @Resource @Qualifier ("defaultFile") בטל הרווחים הציבורי setAnotherArbDependency (File anotherArbDependency) {this.anotherArbDependency = AnotherArbDependency; }}

מטרת המבחן היא להדגים כי גם אם מוגדרים יישומי שעועית מרובים מסוג מסוים בהקשר של יישום, א @מַגְדִיר ניתן להשתמש בהערה יחד עם ה- @מַשׁאָב ביאור לפתרון תלות.

בדומה להזרקת תלות מבוססת שדה, אם מוגדרים שעועית מרובה בהקשר של יישום, א NoUniqueBeanDefinitionException נזרק אם לא @מַגְדִיר ביאור משמש כדי לציין באיזה שעועית יש להשתמש כדי לפתור תלות.

3. ה @לְהַזרִיק ביאור

ה @לְהַזרִיק ביאור שייך לאוסף ההערות JSR-330. להערה זו יש את נתיבי הביצוע הבאים, המפורטים לפי עדיפות:

  1. התאמה לפי סוג
  2. התאמה לפי מוקדמות
  3. התאמה לפי שם

נתיבי ביצוע אלה ישימים הן לקובע והן להזרקת שדה. על מנת לגשת ל @לְהַזרִיק ביאור, ה javax.inject יש להכריז על הספרייה כתלות של Gradle או Maven.

עבור Gradle:

testCompile קבוצה: 'javax.inject', שם: 'javax.inject', גרסה: '1'

עבור מייבן:

 javax.inject javax.inject 1 

3.1. הזרקת שדה

3.1.1. התאמה לפי סוג

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

@Component class class ArbitraryDependency {private final String label = "תלות שרירותית"; מחרוזת ציבורית toString () {תווית החזרה; }}

ה FieldInjectTest מבחן האינטגרציה המדובר מופיע כדלקמן:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, classes = ApplicationContextTestInjectType.class) class public FieldInjectIntegrationTest {@ Inject private ArbitraryDependency fieldInjectDependency; @ מבט בטל פומבי givenInjectAnnotation_WhenOnField_ThenValidDependency () {assertNotNull (fieldInjectDependency); assertEquals ("תלות שרירותית", fieldInjectDependency.toString ()); }}

לא כמו ה @מַשׁאָב ביאור, אשר פותר תלות לפי שם ראשון; התנהגות ברירת המחדל של @לְהַזרִיק ביאור פותר תלות לפי סוג.

המשמעות היא שגם אם שם משתנה הפניה למחלקה שונה משם השעועית, התלות עדיין תיפתר, בתנאי שהשעועית מוגדרת בהקשר היישום. שים לב כיצד שם המשתנה להפניה במבחן הבא:

@ הזרק שדה ArbitraryDependency פרטיInjectDependency;

שונה משם שעועית שהוגדר בהקשר היישום:

@Bean הציבור ArbitraryDependency injectDependency () {ArbitraryDependency injectDependency = חדש ArbitraryDependency (); החזר הזרקת תלות; }

וכאשר הבדיקה מבוצעת, היא מסוגלת לפתור את התלות.

3.1.2. התאמה לפי מוקדמות

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

בדוגמה זו, אנו מחלקים את ה- sub תלות שרירותית class, המשמש בדוגמה לפי התאמה לפי סוג, ליצירת ה- תלות שרירותית אחרת מעמד:

מעמד ציבורי AnotherArbitraryDependency מרחיב ArbitraryDependency {private final String label = "עוד תלות שרירותית"; מחרוזת ציבורית toString () {תווית החזרה; }}

המטרה של כל מקרה מבחן היא להבטיח שכל תלות מוזרקת כהלכה לכל משתנה ייחוס:

@ הזריק DefaultDependency פרטי ArbitraryDependency; @ הזריק תלות שרירותית פרטית בשם תלות;

ה FieldQualifierInjectTest מבחן שילוב המשמש להדגמת התאמה לפי מוקדמות מופיע כדלקמן:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, classes = ApplicationContextTestInjectQualifier.class) מחלקה ציבורית FieldQualifierInjectIntegrationTest {@ Inject private ArbitraryDependency defaultDependency; @ הזריק תלות שרירותית פרטית בשם תלות; @Test public void givenInjectQualifier_WhenOnField_ThenDefaultFileValid () {assertNotNull (defaultDependency); assertEquals ("תלות שרירותית", defaultDependency.toString ()); } @Test ציבורי בטל givenInjectQualifier_WhenOnField_ThenNamedFileValid () {assertNotNull (defaultDependency); assertEquals ("תלות שרירותית נוספת", בשםDependency.toString ()); }}

אם יש מספר יישומים של מחלקה מסוימת בהקשר של יישום FieldQualifierInjectTest מבחן אינטגרציה מנסה להזרים את התלות באופן המפורט להלן:

@ הזריק ברירת מחדל תלות ברירת מחדל תלות; @ הזריק תלות שרירותית פרטית בשם תלות;

א NoUniqueBeanDefinitionException ייזרק.

הטלת חריג זה היא דרכה של Spring Framework לציין שיש מספר יישומים של מעמד מסוים והיא מבולבלת באיזה מהם להשתמש. על מנת להבהיר את הבלבול, עבור לשורה 7 ו -10 של ה- FieldQualifierInjectTest מבחן האינטגרציה:

@ הזריק ברירת מחדל תלות ברירת מחדל תלות; @ הזריק תלות שרירותית פרטית בשם תלות;

העבירו את שם השעועית הנדרש ל @מַגְדִיר ביאור, המשמש יחד עם @לְהַזרִיק ביאור. גוש הקוד ייראה כעת כדלקמן:

@Inject @Qualifier ("defaultFile") פרטיות ArbitraryDependency defaultDependency; @Inject @Qualifier ("namedFile") פרטי תלות שרירותית בשם תלות;

ה @מַגְדִיר ההערה מצפה להתאמה קפדנית בעת קבלת שם שעועית. ודא כי שם השעועית מועבר ל מַגְדִיר נכון, אחרת, א NoUniqueBeanDefinitionException ייזרק. הפעל את המבחן שוב, והפעם הוא אמור לעבור.

3.1.3. התאמה לפי שם

ה FieldByNameInjectTest מבחן שילוב המשמש להדגמת התאמה לפי שם דומה לנתיב ביצוע התאמה לפי סוג. ההבדל היחיד הוא שכעת נדרשת שעועית ספציפית, בניגוד לסוג מסוים. בדוגמה זו, אנו מחלקים את ה- sub תלות שרירותית בכיתה שוב כדי לייצר את עם זאת תלות אחרת שרירותית מעמד:

מעמד ציבורי YetAnotherArbitraryDependency מרחיב ArbitraryDependency {private final String label = "Yet Another arbitrary Dependency"; מחרוזת ציבורית toString () {תווית החזרה; }}

על מנת להדגים את נתיב הביצוע לפי התאמה לפי שם, נשתמש במבחן האינטגרציה הבא:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, classes = ApplicationContextTestInjectName.class) מחלקה ציבורית FieldByNameInjectIntegrationTest {@ Inject @Named ("yetAnotherFieldInjectDependencyDependency); @Test public void givenInjectQualifier_WhenSetOnField_ThenDependencyValid () {assertNotNull (yetAnotherFieldInjectDependency); assertEquals ("עוד תלות שרירותית", yetAnotherFieldInjectDependency.toString ()); }}

הקשר היישום מופיע כדלקמן:

@Configuration public class ApplicationContextTestInjectName {@Bean Public ArbitraryDependency yetAnotherFieldInjectDependency () {ArbitraryDependency yetAnotherFieldInjectDependency = new YetAnotherArbitraryDependency (); להחזיר yetAnotherFieldInjectDependency; }}

הפעל את מבחן האינטגרציה כמו שהוא, והוא יעבור.

כדי לוודא שהתלות אכן הוזרקה על ידי נתיב הביצוע לפי התאמה, שנה את הערך, yetAnotherFieldInjectDependency, שהועבר ל @ שמות ביאור לשם אחר לבחירתך. הפעל את המבחן שוב - הפעם, א NoSuchBeanDefinitionException נזרק.

3.2. הזרקת סתר

הזרקה מבוססת סתר ל @לְהַזרִיק ביאור דומה לגישה בה נעשה שימוש @מַשׁאָב הזרקה מבוססת סטר. במקום לשים לב למשתנה הייחוס, מציינת את הערת שיטת הקובע המתאימה. נתיבי הביצוע ואחריהם הזרקת תלות מבוססת שדה חלים גם על הזרקה מבוססת סטרים.

4. ה @Autowired ביאור

ההתנהגות של @Autowired ההערה דומה ל- @לְהַזרִיק ביאור. ההבדל היחיד הוא שה- @Autowired ביאור הוא חלק ממסגרת האביב. להערה זו יש את אותם נתיבי ביצוע כמו @לְהַזרִיק ביאור, רשום לפי סדר העדיפות:

  1. התאמה לפי סוג
  2. התאמה לפי מוקדמות
  3. התאמה לפי שם

נתיבי ביצוע אלה ישימים הן לקובע והן להזרקת שדה.

4.1. הזרקת שדה

4.1.1. התאמה לפי סוג

הדוגמה לבדיקת שילוב המשמשת להדגמת ה- @Autowired נתיב הביצוע לפי התאמה לפי סוג יהיה דומה למבחן המשמש להדגמת ה- @לְהַזרִיק נתיב ביצוע בהתאמה לפי סוג. ה FieldAutowiredTest מבחן שילוב המשמש להדגמת התאמה לפי סוג באמצעות ה- @Autowired ביאור מופיע כדלקמן:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, classes = ApplicationContextTestAutowiredType.class) מחלקה ציבורית FieldAutowiredIntegrationTest {@Autowired פרטי שרירותי תלות שדה תלות; @Test הציבור בטל givenAutowired_WhenSetOnField_ThenDependencyResolved () {assertNotNull (fieldDependency); assertEquals ("תלות שרירותית", fieldDependency.toString ()); }}

הקשר היישום למבחן אינטגרציה זה מופיע כדלקמן:

@Configuration public class ApplicationContextTestAutowiredType {@Bean public ArbitraryDependency autowiredFieldDependency () {ArbitraryDependency autowiredFieldDependency = ArbitraryDependency new (); החזר autowiredFieldDependency; }}

מטרת מבחן האינטגרציה היא להדגים שהתאמה לפי סוג מקבלת עדיפות ראשונה על פני נתיבי הביצוע האחרים. הודעה בשורה 8 של FieldAutowiredTest בדיקת שילוב כיצד שם המשתנה המפנה:

@ שדה תלות שרירותי פרטי אוטומטי @ תלות;

שונה לשם השעועית בהקשר היישום:

@Bean ציבורי ArbitraryDependency autowiredFieldDependency () {ArbitraryDependency autowiredFieldDependency = חדש ArbitraryDependency (); החזר autowiredFieldDependency; }

כאשר המבחן יופעל, הוא יעבור.

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

4.1.2. התאמה לפי מוקדמות

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

@Configuration public class ApplicationContextTestAutowiredQualifier {@Bean public ArbitraryDependency autowiredFieldDependency () {ArbitraryDependency autowiredFieldDependency = new ArbitraryDependency (); החזר autowiredFieldDependency; } @ שעועית ציבורי ArbitraryDependency anotherAutowiredFieldDependency () {ArbitraryDependency anotherAutowiredFieldDependency = new AnotherArbitraryDependency (); להחזיר תלות אחרתAutowiredFieldDependency; }}

אם ה FieldQualifierAutowiredTest מבחן האינטגרציה, המופיע להלן, מבוצע:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, classes = ApplicationContextTestAutowiredQualifier.class) שדה ציבורי FieldQualifierAutowiredIntegrationTest {@Autowired Private ArbitraryDependency שדה; @ שדה פרטית שרירותי אוטומטית שדה תלות 2; @Test public void givenAutowiredQualifier_WhenOnField_ThenDep1Valid () {assertNotNull (fieldDependency1); assertEquals ("תלות שרירותית", FieldDependency1.toString ()); } @Test הציבור בטל givenAutowiredQualifier_WhenOnField_ThenDep2Valid () {assertNotNull (fieldDependency2); assertEquals ("תלות שרירותית נוספת", fieldDependency2.toString ()); }}

א NoUniqueBeanDefinitionException ייזרק.

היוצא מן הכלל נובע מהעמימות הנגרמת על ידי שתי השעועית המוגדרת בהקשר היישום. מסגרת האביב אינה יודעת איזו תלות שעועית צריכה להיות חוטית אוטומטית לאיזה משתנה ייחוס. פתור בעיה זו על ידי הוספת ה- @מַגְדִיר ביאור לשורות 7 ו -10 של FieldQualifierAutowiredTest מבחן האינטגרציה:

@ שדה פרטי שדה אוטומטי שדה תלות 1; @ שדה פרטית אוטומטית שדה תלות שדה תלות 2;

כך שגוש הקוד ייראה כך:

@Autowired @Qualifier ("autowiredFieldDependency") פרטי FieldDependency fieldDependency1; @Autowired @Qualifier ("AnotherAutowiredFieldDependency") שדה תלות שדה פרטיDependency2;

הפעל את המבחן שוב, והפעם זה יעבור.

4.1.3. התאמה לפי שם

אותו תרחיש בדיקת שילוב ישמש להדגמת נתיב הביצוע לפי התאמה לפי שם @Autowired ביאור להזרקת תלות בשדה. כאשר חיווי אוטומטי לתלות לפי שם, @ComponentScan יש להשתמש בהערה עם הקשר היישום, ApplicationContextTestAutowiredName:

@Configuration @ComponentScan (basePackages = {"com.baeldung.dependency"}) מחלקה ציבורית ApplicationContextTestAutowiredName {}

ה @ComponentScan ביאור יחפש חבילות לשיעורי Java שסומנו עם ה- @רְכִיב ביאור. לדוגמא, בהקשר היישום, ה- com.baeldung. תלות החבילה תיסרק בכיתות שסומנו עם ה- @רְכִיב ביאור. בתרחיש זה, על מסגרת האביב לזהות את תלות שרירותית בכיתה, שיש בה את @רְכִיב ביאור:

@Component (value = "autowiredFieldDependency") מחלקה ציבורית ArbitraryDependency {private final String label = "Dependrary Dependency"; מחרוזת ציבורית toString () {תווית החזרה; }}

ערך התכונה, autowiredFieldDependency, עבר ל @רְכִיב ביאור, אומר מסגרת האביב כי תלות שרירותית מחלקה היא רכיב בשם autowiredFieldDependency. על מנת שה- @Autowired הערה לפתרון תלות לפי שם, שם הרכיב חייב להתאים לשם השדה שהוגדר ב- FieldAutowiredNameTest מבחן האינטגרציה; אנא עיין בשורה 8:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, classes = ApplicationContextTestAutowiredName.class) מחלקה ציבורית FieldAutowiredNameIntegrationTest {@Autowired פרטי שרירותי תלות autowiredFieldD @Test הציבור בטל givenAutowiredAnnotation_WhenOnField_ThenDepValid () {assertNotNull (autowiredFieldDependency); assertEquals ("תלות שרירותית", autowiredFieldDependency.toString ()); }}

כאשר FieldAutowiredNameTest מבחן האינטגרציה מתנהל כמו שהוא, הוא יעבור.

אבל איך נדע שה- @Autowired ביאור באמת העלה את נתיב ביצוע ההתאמה לפי שם? שנה את שם משתנה הייחוס autowiredFieldDependency לשם אחר לבחירתך ואז הפעל את הבדיקה שוב.

הפעם המבחן ייכשל ו NoUniqueBeanDefinitionException נזרק. בדיקה דומה תהיה לשנות את @רְכִיב ערך תכונה, autowiredFieldDependency, לערך אחר לבחירתך והפעל את המבחן שוב. א NoUniqueBeanDefinitionException גם ייזרק.

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

4.2. הזרקת סתר

הזרקה מבוססת סתר ל @Autowired ביאור דומה לגישה שהוכח @מַשׁאָב הזרקה מבוססת סטר. במקום להוסיף הערה למשתנה הייחוס עם ה- @לְהַזרִיק ביאור, הקובץ המתאים הוא ביאור. נתיבי הביצוע שבעקבותיהם הזרקת תלות מבוססת שדה חלים גם על הזרקה מבוססת סטרים.

5. יישום ההערות הללו

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

5.1. שימוש רחב ביישומים בסינגלטונים באמצעות פולימורפיזם

אם העיצוב הוא כזה שהתנהגויות היישום מבוססות על יישומים של ממשק או מחלקה מופשטת, והתנהגויות אלה משמשות בכל היישום, ואז השתמשו @לְהַזרִיק אוֹ @Autowired ביאור.

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

5.2. תצורת התנהגות יישום גרגירה דקה באמצעות פולימורפיזם

אם העיצוב הוא כזה שליישום יש התנהגות מורכבת, כל התנהגות מבוססת על ממשקים / מחלקות מופשטות שונות, והשימוש בכל אחת מהיישומים הללו משתנה בין היישומים, ואז השתמש @מַשׁאָב ביאור. בתרחיש זה, נתיב ביצוע ברירת המחדל העיקרי הוא התאמה לפי שם.

5.3. הזרקת תלות צריכה להיות מטופלת אך ורק על ידי פלטפורמת ה- EE של ג'קרטה

אם יש מנדט תכנון לכל התלות שיוזרקו על ידי פלטפורמת EE ג'קרטה ולא האביב, הבחירה היא בין @מַשׁאָב ביאור ו @לְהַזרִיק ביאור. עליך לצמצם את ההחלטה הסופית בין שתי ההערות, על סמך נתיב ביצוע ברירת המחדל הנדרש.

5.4. הזרקת תלות צריכה להיות מטופלת אך ורק על ידי מסגרת האביב

אם המנדט הוא לטפל בכל התלות על ידי מסגרת האביב, הבחירה היחידה היא @Autowired ביאור.

5.5. סיכום דיון

הטבלה שלהלן מסכמת את הדיון.

תַרחִישׁ@מַשׁאָב@לְהַזרִיק@Autowired
שימוש רחב ביישומים בסינגלטונים באמצעות פולימורפיזם
תצורת התנהגות יישומית מדורגת באמצעות פולימורפיזם
הזרקת תלות צריכה להיות מטופלת אך ורק על ידי פלטפורמת EE בג'קרטה
הזרקת תלות צריכה להיות מטופלת אך ורק על ידי מסגרת האביב

6. מסקנה

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

את הקוד ששימש במהלך הדיון ניתן למצוא ב- GitHub.


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