CodeGym /בלוג Java /Random-HE /אביב לעצלנים יסוד, מושגי יסוד ודוגמאות עם קוד. חלק 2
John Squirrels
רָמָה
San Francisco

אביב לעצלנים יסוד, מושגי יסוד ודוגמאות עם קוד. חלק 2

פורסם בקבוצה
במאמר הקודם , הסברתי בקצרה מהו אביב ומה זה שעועית והקשר. עכשיו הגיע הזמן לנסות את זה. אני הולך לעשות את זה באמצעות IntelliJ IDEA Enterprise Edition. אבל כל הדוגמאות שלי צריכות לעבוד גם במהדורת הקהילה החינמית של IntelliJ IDEA. בצילומי המסך, אם אתה רואה שיש לי איזה חלון שאין לך, אל תדאג - זה לא חשוב לפרויקט הזה :) אביב לעצלנים יסוד, מושגי יסוד ודוגמאות עם קוד.  חלק 2 - 1ראשית, צור פרוייקט ריק של Maven. הראיתי איך לעשות זאת במאמר בקישור הזה . קרא עד המילים " הגיע הזמן שלנו להמיר את פרויקט Maven שלנו לפרויקט אינטרנט. " - לאחר מכן, המאמר מראה כיצד ליצור פרויקט אינטרנט, אבל אנחנו לא צריכים את זה כרגע. בתיקיית src/main/java צור חבילה (במקרה שלי קראתי לזה " en.codegym.info.fatfaggy.animals. אתה יכול לקרוא לזה איך שאתה רוצה. רק אל תשכח להחליף את שם החבילה שלי בשם החבילה שלך בכל המקומות הנכונים. כעת צור את Mainהמחלקה והוסף שיטה
public static void main(String[] args) {
    ...
}
לאחר מכן, פתח את הקובץ pom.xml והוסף את dependenciesהקטע. כעת עבור אל מאגר Maven ומצא את ההקשר של Spring עבור הגרסה היציבה האחרונה. הכניסו את מה שאנו מוצאים לסעיף dependencies. תיארתי את התהליך הזה ביתר פירוט במאמר אחר זה של CodeGym (ראה את הסעיף שכותרתו " חיבור תלות ב-Maven "). אז Maven עצמה תמצא ותוריד את התלות הדרושות. בסופו של דבר, אתה אמור לקבל משהו כזה: אביב לעצלנים יסוד, מושגי יסוד ודוגמאות עם קוד.  חלק 2 - 2בחלון בצד שמאל, אתה יכול לראות את מבנה הפרויקט עם החבילה והכיתה Main. החלון האמצעי מראה איך pom.xml נראה עבורי. הוספתי לו גם סעיף מאפיינים . סעיף זה אומר ל-Maven באיזו גרסה של Java אני משתמש בקבצי המקור שלי ואיזו גרסה להדר. זה רק כדי ש-IDEA לא מזהיר אותי שאני משתמש בגרסה ישנה של Java. זה אופציונלי :) החלון הימני מבהיר שלמרות שחיברנו רק את מודול הקפיץ-קונטקסט, הוא משך אוטומטית את מודולי הקפיץ-ליבת, הקפיץ-שעועית, קפיץ-אופ וקפיץ-ביטוי. יכולנו לחבר כל מודול בנפרד, לכתוב תלות לכל מודול עם הגרסה המפורשת בקובץ pom.xml, אבל לעת עתה אנחנו מרוצים מהמצב כפי שהם. כעת צור את entitiesהחבילה וצור בה 3 מחלקות: Cat, Dog, Parrot. בוא ניתן לכל חיה שם ( private String name— אתה יכול לקוד כמה ערכים שם). המגדירים/מקבעים הם ציבוריים. עכשיו אנחנו עוברים לכיתה Mainולשיטה main(), ואנחנו כותבים משהו כזה:
public static void main(String[] args) {
	// Create an empty Spring context that will look for its own beans based on the annotations in the specified package
	ApplicationContext context =
		new AnnotationConfigApplicationContext("en.codegym.info.fatfaggy.animals.entities");

	Cat cat = context.getBean(Cat.class);
	Dog dog = (Dog) context.getBean("dog");
	Parrot parrot = context.getBean("parrot-polly", Parrot.class);

	System.out.println(cat.getName());
	System.out.println(dog.getName());
	System.out.println(parrot.getName());
}
ראשית, אנו יוצרים אובייקט הקשר, שאומרים לבנאי באיזו חבילה לחפש כדי למצוא שעועית. במילים אחרות, אביב יעבור על החבילה הזו וינסה למצוא שיעורים המסומנים בהערות מיוחדות המעידות על שעועית. לאחר מכן הוא יוצר את האובייקטים של המחלקות הללו ומכניס אותם להקשר. אחרי זה, אנחנו מקבלים חתול מההקשר הזה. אנו קוראים לאובייקט ההקשר לתת לנו שעועית (אובייקט), המציינת את המחלקה של האובייקט שאנו רוצים (אגב, אנו יכולים גם לציין ממשקים, לא רק מחלקות). לאחר מכן, Spring מחזיר אובייקט מהמחלקה המבוקשת, אותו אנו שומרים במשתנה. לאחר מכן, אנו מבקשים מאביב להביא לנו שעועית בשם "כלב". כאשר Spring יוצר Dogאובייקט, הוא נותן לאובייקט שם סטנדרטי (אלא אם השעועית שנוצרה קיבלה שם במפורש), שהוא שם המחלקה אך עם אות קטנה ראשונית. במקרה זה, הכיתה שלנו נקראת Dog, אז השם של השעועית הוא להיות "כלב". אם היינו צריכים BufferedReaderאובייקט שם, אז אביב היה קורא לו "bufferedReader". ומכיוון ש-Java לא יכולה להיות בטוחה ב-100% איזו מחלקה אנחנו רוצים, היא מחזירה אובייקט Object, שלאחר מכן נטיל אותו ידנית לסוג הרצוי, כלומר Dog. האפשרות שבה המעמד מצוין במפורש נוחה יותר. האפשרות השלישית היא לקבל שעועית לפי שם הכיתה ולפי שם שעועית. ייתכן שההקשר עשוי לכלול כמה שעועית ממחלקה אחת. על מנת לציין את השעועית המסוימת שאנו צריכים, אנו מציינים את שמה. מכיוון שגם כאן אנו מציינים במפורש את המעמד, איננו צריכים עוד לבצע ליהוק. חָשׁוּב!אם אביב מוצא כמה שעועית שתואמות את הדרישות שלנו, אז היא לא יכולה לקבוע איזו שעועית לתת לנו, אז היא תגרום לחריגה. בהתאם לכך, כדי להימנע ממצב זה, כדאי לנסות להיות ספציפיים ככל האפשר לומר לאביב איזו שעועית אתה צריך. אם אביב יחפש את ההקשר שלו ולא יצליח למצוא שעועית אחת שתואמת את הדרישות שלנו, אז היא גם תזרוק חריגה. לבסוף, אנחנו פשוט מציגים את שמות החיות שלנו כדי לוודא שבאמת יש לנו את החפצים שאנחנו צריכים. אבל אם נריץ את התוכנית עכשיו, נראה שאביב לא מרוצה - הוא לא יכול למצוא את החיות שאנחנו צריכים בהקשר שלה. זה בגלל שהוא לא יצר את השעועית האלה. כפי שאמרתי בעבר, כאשר ספרינג סורק שיעורים, הוא מחפש ביאורי אביב משלו. ואם אביב לא מוצא את ההערות האלה, אז הוא לא חושב שהשיעורים האלה מתאימים לשעועית שהוא צריך ליצור. תיקון זה פשוט מצריך הוספת @Componentההערה לפני כל אחת מכיתות החיות שלנו.
@Component
public class Cat {
	private String name = "Oscar";
	...
}
אבל יש עוד. אם אנחנו צריכים לומר במפורש ל-Spring שלשעועית למחלקה זו צריך להיות שם ספציפי, נציין את השם בסוגריים אחרי ההערה. לדוגמה, כדי לומר לאביב לתת את השם " parrot-polly" לשעועית התוכי, שזה השם שבו נשתמש כדי לקבל את התוכי הזה בשיטה main, עלינו לעשות משהו כזה:
@Component("parrot-polly")
public class Parrot {
	private String name = "Polly";
	...
}
זו כל הנקודה של תצורה אוטומטית . אתה כותב את השיעורים שלך, מסמן אותם בהערות הנחוצות, ומספר לאביב את החבילה הכוללת את השיעורים שלך. זו החבילה שהמסגרת תעבור דרכה כדי למצוא הערות וליצור אובייקטים של מחלקות אלה. אגב, ספרינג לא מחפש רק @Componentהערות, אלא גם את כל ההערות האחרות שיורשים את זה. לדוגמה, @Controller, @RestController, @Service, @Repositoryועוד, אותם נציג במאמרים הבאים. כעת ננסה לעשות את אותו הדבר באמצעות תצורה מבוססת Java . כדי להתחיל, הסר את @Componentההערות מהשיעורים שלנו. כדי להפוך את הדברים למאתגרים יותר, דמיינו שלא כתבנו את השיעורים האלה, כך שלא נוכל לשנות אותם בקלות, מה שאומר שאיננו יכולים להוסיף הערות. זה כאילו השיעורים האלה ארוזים באיזו ספרייה. במקרה זה, אין לנו דרך לערוך את המחלקות הללו כך שיזוהו על ידי Spring. אבל אנחנו צריכים אובייקטים של המעמדות האלה! כאן אנחנו צריכים תצורה מבוססת Java כדי ליצור את האובייקטים. כדי להתחיל, צור חבילה בשם כמו configs. בחבילה זו, צור מחלקה רגילה של Java, משהו כמו MyConfig, וסמן אותה עם @Configurationההערה.
@Configuration
public class MyConfig {
}
עכשיו אנחנו צריכים לשנות את main()השיטה, לשנות את האופן שבו אנחנו יוצרים את ההקשר. אנחנו יכולים לציין במפורש לאיזו מחלקה יש את התצורה שלנו:
ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class);
אם יש לנו כמה מחלקות שונות שיוצרות שעועית ואנו רוצים לחבר כמה מהן בו זמנית, אנחנו פשוט מציינים את כולם שם, מופרדים בפסיקים:
ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class, MyAnotherConfig.class);
ואם יש לנו יותר מדי מהם ואנחנו רוצים לחבר את כולם בו זמנית, אז אנחנו פשוט מציינים את שם החבילה שהם כלולים בה:
ApplicationContext context =
	new AnnotationConfigApplicationContext("en.codegym.info.fatfaggy.animals.configs");
במקרה זה, אביב יעבור על החבילה וימצא את כל השיעורים המסומנים בהערה @Configuration. ובכן, ואם יש לנו תוכנית ממש גדולה שבה התצורות מחולקות לחבילות שונות, אז אנחנו פשוט מציינים רשימה מופרדת בפסיקים של שמות החבילות שמכילות את התצורות:
ApplicationContext context =
	new AnnotationConfigApplicationContext("en.codegym.info.fatfaggy.animals.database.configs",
		"en.codegym.info.fatfaggy.animals.root.configs",
		"en.codegym.info.fatfaggy.animals.web.configs");
או שם של חבילה שמשותף לכולם:
ApplicationContext context =
	new AnnotationConfigApplicationContext("en.codegym.info.fatfaggy.animals");
אתה יכול לעשות את זה איך שאתה רוצה, אבל נראה לי שהאפשרות הראשונה, שפשוט מציינת מחלקה עם הקונפיגורציות, תתאים ביותר לתוכנית שלנו. בעת יצירת הקשר, Spring מחפש מחלקות המסומנות בהערה @Configurationוייצור אובייקטים משלו של מחלקות אלו. הוא מנסה לקרוא לשיטות המסומנות עם @Beanההערה, מה שאומר ששיטות אלו מחזירות שעועית (אובייקטים) ש-Spring יוסיף להקשר. ועכשיו ניצור שעועית עבור חתול, כלב ותוכי בכיתה שלנו עם תצורה מבוססת Java. זה די פשוט לביצוע:
@Bean
public Cat getCat() {
	return new Cat();
}
כאן אנו יוצרים ידנית את החתול שלנו ומעבירים אותו לאביב, אשר לאחר מכן מחזיק את החפץ שלנו בהקשר שלו. מכיוון שלא נתנו שם במפורש לשעועית שלנו, אביב ייתן לה את אותו שם כמו שם השיטה. במקרה שלנו, שעועית החתול תיקרא " getCat". אבל בגלל שאנחנו משתמשים בכיתה, לא בשם, כדי לקבל את שעועית החתול בשיטה main, השם של השעועית לא חשוב לנו. באופן דומה, צור שעועית לכלב, תוך התחשבות שאביב ייתן את שם השיטה לשעועית. כדי לתת שם מפורש לשעועית התוכי שלנו, אנו פשוט מציינים את שמה בסוגריים אחרי @Beanההערה:
@Bean("parrot-polly")
public Object weNeedMoreParrots() {
	return new Parrot();
}
כפי שניתן לראות, כאן ציינתי Objectסוג החזרה ונתתי לשיטה שם שרירותי. זה לא משפיע על שם השעועית, מכיוון שציינו כאן במפורש את השם. ובכל זאת, עדיף לציין ערך החזרה ושם שיטה משמעותיים יותר או פחות. עשה זאת אם אין סיבה אחרת מלבד לעשות לעצמך טובה כשאתה פותח מחדש את הפרויקט בעוד שנה. :) עכשיו שקול את המצב שבו אנחנו צריכים שעועית אחת כדי ליצור שעועית אחרת . לדוגמה, נניח שאנו רוצים ששם החתול בשעועית החתול יהיה שם התוכי בתוספת המחרוזת "-רוצח". אין בעיה!
@Bean
public Cat getCat(Parrot parrot) {
	Cat cat = new Cat();
	cat.setName(parrot.getName() + "-killer");
	return cat;
}
כאן אביב יראה שכדי ליצור את השעועית הזו, המסגרת צריכה לעבור בשעועית התוכי שנוצרה בעבר. בהתאם, הוא יסדר את שרשרת הקריאות המתודה הנדרשת: ראשית, נקראת השיטה ליצירת תוכי ולאחר מכן המסגרת מעבירה את התוכי החדש לשיטת יצירת החתול. כאן נכנסת לתמונה הזרקת תלות : האביב עצמו מעביר את שעועית התוכי הנדרשת לשיטה שלנו. אם IDEA מתעצבן על parrotהמשתנה, אל תשכח לשנות את סוג ההחזרה של שיטת יצירת התוכים מ- Objectל Parrot. בנוסף, תצורה מבוססת Java מאפשרת לך להריץ כל קוד Java בשיטות יצירת השעועית שלך. אתה באמת יכול לעשות הכל: ליצור אובייקטים עזר אחרים, לקרוא לכל שיטות אחרות, אפילו אלה שאינן מסומנות עם הערות Spring, ליצור לולאות, תנאים בוליאניים - מה שעולה על דעתך! לא הכל אפשרי עם תצורה אוטומטית, ועוד פחות מכך עם תצורת XML. עכשיו בואו נשקול בעיה שהיא קצת יותר מהנה. פולימורפיזם וממשקים :) ניצור WeekDayממשק וניצור 7 מחלקות שמיישמות את הממשק הזה: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. ניתן לממשק שיטה String getWeekDayName(), שתחזיר את שם היום בשבוע עבור הכיתה המקבילה. במילים אחרות, Mondayהכיתה תחזיר " Monday" וכו'. עם תחילת היישום, נניח שהמשימה שלנו היא להכניס שעועית המתאימה ליום הנוכחי בשבוע בהקשר. לא שעועית לכל המחלקות שמיישמות את WeekDayהממשק - רק השעועית האחת שאנחנו צריכים. אתה יכול לעשות את זה בערך ככה:
@Bean
public WeekDay getDay() {
	DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();
	switch (dayOfWeek) {
		case MONDAY: return new Monday();
		case TUESDAY: return new Tuesday();
		case WEDNESDAY: return new Wednesday();
		case THURSDAY: return new Thursday();
		case FRIDAY: return new Friday();
		case SATURDAY: return new Saturday();
		default: return new Sunday();
	}
}
כאן סוג ההחזרה הוא הממשק שלנו. השיטה מחזירה אובייקט בתום לב של אחת המחלקות שמיישמות את הממשק, בהתאם ליום הנוכחי בשבוע. כעת נוכל לעשות את הדברים הבאים בשיטה main():
WeekDay weekDay = context.getBean(WeekDay.class);
System.out.println("Today is " + weekDay.getWeekDayName() + "!");
מבחינתי, התוכנית אומרת לי שזה יום ראשון :) אני בטוח שאם אפעיל את התוכנית מחר, ההקשר יכיל אובייקט אחר לגמרי. שים לב שאנו מקבלים את השעועית פשוט באמצעות הממשק: context.getBean(WeekDay.class). Spring יחפש את ההקשר שלו אחר השעועית המיישמת את הממשק, ויחזיר אותו. ואז מסתבר שהמשתנה שלנו WeekDayמסתיים באובייקט של יום ראשון, והמושג המוכר של פולימורפיזם חל כשאנחנו עובדים עם המשתנה הזה. :) עכשיו כמה מילים על הגישה המשולבת , שבה חלק מהשעועית נוצרת אוטומטית על ידי Spring, חלק על ידי סריקת חבילות למחלקות עם ההערה @Component, ואחרות על ידי תצורה מבוססת Java. כאשר אנו שוקלים זאת, נחזור לגרסה המקורית, שבה סומנו ה- Cat, Dog, והשיעורים Parrotעם @Componentההערה. נניח שאנחנו רוצים ליצור שעועית לבעלי החיים שלנו על ידי כך שאביב יסרוק אוטומטית את entitiesהחבילה, אבל אנחנו גם רוצים ליצור שעועית עם היום בשבוע, כמו שעשינו זה עתה. כל מה שצריך לעשות הוא להוסיף את @ComponentScanההערה ברמת המחלקה MyConfig, אותה אנו מציינים בעת יצירת ההקשר ב- main(), ולציין בסוגריים את החבילה שצריך לסרוק וליצור שעועית של המחלקות הנחוצות באופן אוטומטי:
@Configuration
@ComponentScan("en.codegym.info.fatfaggy.animals.entities")
public class MyConfig {
	@Bean
	public WeekDay getDay() {
		DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();
		switch (dayOfWeek) {
			case MONDAY: return new Monday();
			case TUESDAY: return new Tuesday();
			case WEDNESDAY: return new Wednesday();
			case THURSDAY: return new Thursday();
			case FRIDAY: return new Friday();
			case SATURDAY: return new Saturday();
			default: return new Sunday();
		}
	}
}
כשיוצרים את ההקשר, אביב רואה שהוא צריך לעבד את MyConfigהכיתה. הוא נכנס למחלקה ורואה שהוא צריך לסרוק את en.codegym.info.fatfaggy.animals.entitiesהחבילה " " וליצור שעועית של המחלקות הללו, ולאחר מכן הוא מבצע את השיטה MyConfigשל ​​המחלקה getDay()ומוסיף WeekDayשעועית להקשר. בשיטה main()יש לנו עכשיו גישה לכל השעועית שאנחנו צריכים: גם חפצים של בעלי חיים וגם שעועית עם היום בשבוע. אם אי פעם תצטרך לגרום ל-Spring גם לאסוף כמה קובצי תצורה של XML, אתה יכול לעשות חיפוש אינטרנט משלך כדי למצוא הסבר :) סיכום:
  • נסה להשתמש בתצורה אוטומטית
  • במהלך התצורה האוטומטית, ציין את שם החבילה המכילה את המחלקות שיש ליצור את הפולים שלהן
  • שיעורים אלה מסומנים עם @Componentההערה
  • אביב עובר דרך כל המחלקות הללו, יוצר אובייקטים ומכניס אותם להקשר;
  • אם תצורה אוטומטית לא מתאימה לנו מסיבה כלשהי, אנו משתמשים בתצורה מבוססת Java
  • במקרה זה, אנו יוצרים מחלקת Java רגילה שהשיטות שלה מחזירות את האובייקטים שאנו צריכים. אנו מסמנים את המחלקה הזו עם @Configurationההערה אם אנחנו מתכוונים לסרוק את כל החבילה במקום לציין מחלקה ספציפית עם התצורה בעת יצירת ההקשר
  • השיטות של מחלקה זו המחזירות שעועית מסומנות עם @Beanההערה
  • אם ברצוננו לאפשר סריקה אוטומטית בעת שימוש בתצורה מבוססת Java, אנו משתמשים בהערה @ComponentScan.
אם מאמר זה היה מבלבל לחלוטין, נסה לקרוא אותו בעוד מספר ימים. או אם אתה באחת מהרמות המוקדמות של CodeGym, יכול להיות שזה קצת מוקדם בשבילך ללמוד אביב. אתה תמיד יכול לחזור למאמר זה קצת מאוחר יותר כאשר אתה מרגיש בטוח יותר בכישורי התכנות שלך ב-Java. אם הכל ברור, אז אתה יכול לנסות להמיר איזה פרויקט חיית מחמד שלך לאביב :) אם חלק מהדברים ברורים אבל אחרים דברים לא, אנא השאירי תגובה :) תן לי לדעת את ההצעות והביקורות שלך, אם טעיתי איפשהו או כתבנו שטויות :) במאמר הבא, נצלול בפתאומיות אל spring-web-mvc וניצור יישום אינטרנט פשוט באמצעות Spring.
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION