האביב הוא אולי מיטב המסגרות המבוססות על רכיבים שהופיעו בתחילת המאה ה -21. זה משפר מאוד את הדרך שבה מפתחים כותבים ומספקים קוד תשתית ביישומים מבוססי Java. מאז הקמתה, Spring הוכרה כמסגרת מובילה לפיתוח Java ארגוני. כמסגרת יישומים מקצה לקצה, Spring משקף חלק מיכולות ה- Java EE, אך הוא מציע שילוב של תכונות ומוסכמי תכנות שלא תמצאו במקום אחר.
מאמר זה מציג את אביב ואת פילוסופיית התכנות והמתודולוגיה המרכזית שלה: היפוך שליטה והזרקת תלות. תוכלו גם להתחיל עם הערות אביביות וכמה דוגמאות קידוד מעשיות.
הזרקת תלות והיפוך שליטה
הרעיון המרכזי של אביב הוא שבמקום לנהל בעצמך יחסי אובייקט אתה מוריד אותם למסגרת. היפוך שליטה (IOC) הוא המתודולוגיה המשמשת לניהול יחסי אובייקט. הזרקת תלות היא המנגנון ליישום IOC. מכיוון ששני המושגים הללו קשורים אך שונים, הבה נבחן אותם מקרוב:
- היפוך שליטה (IOC) עושה בדיוק את מה ששמו אומר: הוא הופך את ההיררכיה המסורתית של שליטה למימוש יחסי אובייקט. במקום להסתמך על קוד יישום כדי להגדיר את האופן שבו אובייקטים קשורים זה לזה, מערכות היחסים מוגדרות על ידי המסגרת. כמתודולוגיה, IOC מציג עקביות וחיזוי להתנגדות ביחסים, אך הוא מחייב אותך כמפתח לוותר על שליטה דקה.
- הזרקת תלות (DI) היא מנגנון שבו המסגרת "מזריקה" תלות באפליקציה שלך. זה היישום המעשי של ה- IOC. הזרקת תלות תלויה בפולימורפיזם, במובן זה שהיא מאפשרת מימוש של סוג התייחסות לשינוי בהתבסס על תצורות במסגרת. המסגרת מזריקה הפניות משתנות במקום למלא אותן באופן ידני בקוד היישום.
JSR-330
כמו הרבה בעולם ג'אווה, מה שהתחיל כחידוש בטבע, אביב, נקלט בחלקו במפרט הסטנדרטי. במקרה זה, JSR-330 הוא תקן Java. הדבר הנחמד במפרט JSR-330 הוא שתוכל להשתמש בו במקום אחר, ותראה אותו בשימוש במקום אחר, מעבר לאביב. אתה יכול להשתמש בו מבלי להשתמש באביב. עם זאת, אביב מביא הרבה יותר לשולחן.
דוגמה מס '1: הזרקת תלות באביב
היפוך שליטה והזרקת תלות מובנים בצורה הטובה ביותר על ידי שימוש בהם, לכן נתחיל בדוגמה תכנותית מהירה.
תגיד שאתה מדגמן מכונית. אם אתה מדגמן ב- Java ישנה רגילה, ייתכן שיהיה חבר ממשק Car
בכיתה שיתייחס Engine
לממשק, כפי שמוצג ברשימה 1.
רישום 1. יחסי אובייקט בג'אווה ישנה רגילה
public Interface Engine() { ... } public class Car { private Engine engine; public Engine getEngine() { ... } public void setEngine(Engine engine) { ... } }
רישום 1 מכיל ממשק Engine
לסוג, ומחלקה Car
לסוג הבטון , המפנה ל Engine
. (שים לב שבתרחיש תכנות אמיתי אלה יהיו בקבצים נפרדים.) כעת, כאשר אתה יוצר Car
מופע, היית מגדיר את השיוך כפי שמוצג ברשימה 2.
רישום 2. יצירת רכב עם ממשק המנוע
// ... Car newCar = new Car(); Engine sixCylEngine = new InlineSixCylinderEngine(); newCar.setEngine(sixCylEngine ); // Do stuff with the car
שים לב שתיצור Car
תחילה את האובייקט. לאחר מכן אתה יוצר אובייקט חדש שממלא את Engine
הממשק, ומקצה אותו ידנית Car
לאובייקט. כך פועלים אסוציאציות אובייקטים בג'אווה ישנה פשוטה.
דוגמנות שיעורים וחפצים באביב
עכשיו בואו נסתכל על אותה דוגמא באביב. הנה, אתה יכול לעשות משהו כמו מה שמוצג מודעה 3. אתה מתחיל עם Car
הכיתה, אבל במקרה הזה אתה מוסיף ביאור אליו: @Inject
.
רישום 3. דוגמה לשימוש בהערת @Inject באביב
public class Car { @Inject private Engine engine; // ... }
שימוש @Inject
בהערה (או @Autowired
, אם אתה מעדיף) אומר לאביב לחפש את ההקשר ולהזריק אובייקט באופן אוטומטי להפניה, בהתבסס על מערכת כללים.
לאחר מכן שקול את @Component
ההערה המוצגת ברשימה 4.
רישום 4. הערת @ רכיב
@Component public class InlineSixCylinderEngine implements Engine{ //... }
ביאור לשיעור איתו @Component
אומר לאביב שהוא זמין למימוש זריקות. במקרה זה, InlineSixCylEngine
יוזרק כי הוא זמין ועונה על דרישת הממשק של העמותה. באביב זה נקרא זריקה "אוטומטית". (ראה להלן מידע נוסף על @Autowired
ההערה של אביב ).
ניתוק כעקרון עיצובי
היפוך שליטה באמצעות הזרקת תלות מסיר מקור לתלות קונקרטית מהקוד שלך. בשום מקום בתוכנית אין התייחסות מקודדת Engine
ליישום. זוהי דוגמה להתנתקות כעקרון עיצוב תוכנה. ניתוק קוד היישום מההטמעה מקל על ניהול ותחזוקת הקוד שלך. היישום יודע פחות כיצד חלקיו משתלבים זה בזה, אך הרבה יותר קל לבצע שינויים בכל נקודה במחזור החיים של היישום.
@Autowired לעומת @ Inject
@Autowired
ו @Inject
לעשות את אותו הדבר. עם זאת, @Inject
ההערה הסטנדרטית של Java @Autowired
היא , ואילו היא ספציפית לאביב. שניהם משרתים את אותה מטרה לומר למנוע ה- DI להזריק את השדה או השיטה עם אובייקט תואם. אתה יכול להשתמש באחד מהם באביב.
סקירה של מסגרת האביב
עכשיו, כשראיתם קוד קוד, בואו ניקח סקירה כללית של המסגרת ומרכיביה. כפי שאתה יכול לראות, המסגרת מורכבת מארבעה מודולים עיקריים, המתפרקים לחבילות. אביב נותן לך מידה לא מבוטלת של גמישות עם המודולים בהם תשתמש.
- מיכל ליבה
- הליבה
- אפונה
- הֶקשֵׁר
- שפת ביטוי
- תכנות מונחה היבטים (AOP)
- AOP
- היבטים
- מִכשׁוּר
- גישה ושילוב נתונים
- JDBC
- JPA / ORM
- JMS
- עסקאות
- אינטרנט
- אינטרנט / מנוחה
- סרוולט
- תמוכות
במקום לכסות הכל כאן, בואו נתחיל בשתיים מתכונות האביב הנפוצות יותר.
הקמת פרויקט חדש: Spring Boot
נשתמש באביב אתחול כדי ליצור פרויקט לדוגמה, בו נשתמש להדגמת תכונות אביב. Spring Boot מקל על התחלת פרויקטים חדשים, כפי שתראו בעצמכם. כדי להתחיל, התבונן במחלקה הראשית המוצגת למטה. באביב אתחול, אנו יכולים לקחת מעמד ראשי main()
בשיטה, ואז לבחור להפעיל אותו עצמאי, או לארוז לפריסה במיכל כמו Tomcat.
ברשימה 5 יש קווי מתאר של המעמד הראשי שלנו, שיחיה src/main/java/hello
במיקום הסטנדרטי .
רישום 5. מחלקה ראשית עם מגף אביב
package hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
שימו לב לשני דברים לגבי הקוד הנ"ל: ראשית, כל העבודות מופשטות למסגרת. המעמד הראשי מאתחל את האפליקציה, אך הוא אינו יודע דבר על האופן בו האפליקציה פועלת או מספקת את הפונקציונליות שלה. שנית, SpringApplication.run()
זה עושה את העבודה בפועל לאתחל את האפליקציה ולעבור Application
בכיתה עצמה. שוב, העבודה שהאפליקציה עושה אינה ניכרת כאן.
@SpringBootApplication
הביאור עוטף כמה בהערות סטנדרטיות ואומר אביב להסתכל על החבילה שבה המעמד המרכזי קיים עבור רכיבים. בדוגמה הקודמת שלנו, עם המכונית והמנוע, זה יאפשר לאביב למצוא את כל הכיתות המוערות עם @Component
ו @Inject
. התהליך עצמו, הנקרא סריקת רכיבים , ניתן להתאמה אישית רבה.
אתה יכול לבנות את האפליקציה עם התקן mvn clean install
, ואתה יכול להריץ אותה עם מטרת Spring Boot ( mvn spring-boot:run
). לפני שנעשה זאת, בואו נסתכל על pom.xml
קובץ היישום הזה .
רישום 6. Starter pom.xml
com.javaworld what-is-spring 1.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE 1.8 org.springframework.boot spring-boot-maven-plugin
שימו לב לשתי תכונות חשובות בקוד שלעיל:
parent
האלמנט מסתמך עלspring-boot-starter-parent
הפרויקט. פרויקט אב זה מגדיר מספר ברירות מחדל שימושיות, כגון רמת המהדר המוגדרת כברירת מחדל של JDK 1.8. לרוב, אתה יכול פשוט לסמוך שהוא יודע מה הוא עושה. כדוגמה, אתה יכול להשמיט את מספר הגירסה עבור הרבה תלות נפוצה,SpringBootParent
ותגדיר את הגרסאות להיות תואמות. כאשר אתה מקפיץ את מספר הגרסה של ההורה, גם גרסאות התלות והברירות המחדל ישתנו.spring-boot-maven-plugin
מאפשר JAR הפעלה / WAR האריזה ב-מקוםrun
(דרךmvn spring-boot:run
הפקודה).
הוספת רשת האביב כתלות
עד כה הצלחנו להשתמש spring-boot
בכדי להגביל כמה עבודה השקענו בכדי להפעיל אפליקציה. עכשיו בואו נוסיף תלות ונראה כמה מהר נוכל להשיג משהו בדפדפן.
רישום 7. הוספת Spring Web לפרויקט
org.springframework.boot spring-boot-starter-web
הערה
אביב יאתר אוטומטית אילו קבצים השתנו ויקבץ בהתאם. אתה יכול פשוט לבצע mvn spring-boot:run
שינויים באיסוף.
כעת, לאחר שהגדרנו פרויקט בסיסי, אנו מוכנים לשתי הדוגמאות שלנו.
דוגמה מס '2: בניית נקודות קצה מנוחות עם Spring Spring
פעם היינו spring-boot-starter-web
מביאים כמה תלות שימושיות לבניית יישומי אינטרנט. בשלב הבא ניצור מטפל בנתיב עבור נתיב URL. תמיכת האינטרנט של Spring היא חלק ממודול Spring MVC (Model-View-Controller), אך אל תתנו לזה להדאיג אתכם: ל- Spring Web יש תמיכה מלאה ויעילה גם לבניית נקודות קצה RESTful.
המחלקה שתפקידה לשדות בקשות לכתובות אתרים ידועה כבקר , כפי שמוצג ברשימה 8.
רישום 8. בקר MVC REST באביב
package hello; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RequestParam; @Controller public class GreetingController { @RequestMapping(value = "/hi", method = RequestMethod.GET) public String hi(@RequestParam(name="name", required=false, defaultValue="JavaWorld") String name, Model model) { return "Hello " + name; } }
ההערה של @Controller
@Controller
הביאור מזהה מחלקה כבקר. מחלקה המסומנת כבקר גם מזוהה אוטומטית כמחלקת רכיבים, מה שהופך אותה למועמדת לחיווט אוטומטי. בכל מקום בו יש צורך בבקר זה, הוא יחובר למסגרת. במקרה זה, נחבר אותו למערכת MVC בכדי לטפל בבקשות.
הבקר הוא סוג מיוחד של רכיב. הוא תומך @RequestMapping
ואת @ResponseBody
ההסברים שאתה רואה על hi()
השיטה. ביאורים אלה מציגים את המסגרת כיצד למפות בקשות URL לאפליקציה.
בשלב זה תוכלו להריץ את האפליקציה באמצעות mvn spring-boot:run
. כשתלחץ על /hi
כתובת האתר תקבל תגובה כמו "שלום, JavaWorld".
שימו לב כיצד אביב לקח את היסודות של רכיבי חיווט אוטומטי, ומסר מסגרת אינטרנטית שלמה. עם אביב אתה לא צריך לחבר שום דבר במפורש ביחד!
ההערות של @Request
זה @RequestMapping
מאפשר לך להגדיר מטפל לנתיב URL. האפשרויות כוללות הגדרת שיטת HTTP הרצויה, וזה מה שעשינו במקרה זה. RequestMethod
הפסקת פעולה תנחה את התוכנית לטפל בכל סוגי שיטות ה- HTTP.
@RequestParam
ביאור הטיעון מאפשר לנו למפות את פרמטרי הבקשה ישירות לתוך חתימת השיטה, כולל מחייב פרמטרים מסוימים והגדרת ערכי ברירת מחדל כפי שעשינו כאן. אנו יכולים אפילו למפות גוף בקשה לכיתה עם @RequestBody
הערת הטיעון.
תגובת REST ו- JSON
אם אתה יוצר נקודת קצה של REST וברצונך להחזיר את JSON מהשיטה, אתה יכול להוסיף הערה לשיטה באמצעות @ResponseBody
. התגובה תארוז אוטומטית כ- JSON. במקרה זה תחזיר אובייקט מהשיטה.
שימוש ב- MVC עם Spring Web
בדומה ל- Struts, ניתן להשתמש בקלות במודול ה- Spring Web לצורך הגדרת בקר-מודל-מבט אמיתי. במקרה כזה, היית מחזיר מיפוי בשפת התבניות הנתונה (כמו Thymeleaf), ו- Spring היה פותר את המיפוי, מספק את המודל שאתה מעביר אליו ומגיש את התגובה.
דוגמה מס '3: אביב עם JDBC
עכשיו בואו נעשה משהו מעניין יותר עם מטפל הבקשות שלנו: בואו נחזיר כמה נתונים ממסד נתונים. לצורך דוגמה זו נשתמש במסד הנתונים H2. למרבה המזל, Spring Boot תומך ב- H2 DB בזיכרון מהקופסה.