أساسيات Spring Boot

المبدئيات والتبعيات

18 دقيقة الدرس 3 من 13

المبدئيات والتبعيات

من أبرز المساهمات العملية لـ Spring Boot مفهوم starter POM. بدلًا من البحث في الوثائق لمعرفة المكتبات الخمس التي تحتاجها لبناء REST API — ثم اكتشاف في منتصف المشروع أن إصداراتها غير متوافقة — تُعلن عن starter واحد وتتولى Spring Boot سحب مجموعة مُختبَرة ومتوافقة نيابةً عنك. يشرح هذا الدرس كيف تعمل هذه المبدئيات، وما توفره الأكثر أهمية منها، وكيف تفهم شجرة التبعيات وتتحكم فيها.

ما هو الـ Starter؟

الـ starter تبعية Maven أو Gradle عادية يحتوي ملف JAR الخاص بها على كمية ضئيلة من الكود. مهمته الوحيدة هي الإعلان عن تبعيات متعدية تشير إلى المكتبات الحقيقية. عند حل spring-boot-starter-web، يجلب Maven أو Gradle مكتبات Spring MVC وخادم Tomcat المدمج وJackson لتسلسل JSON ودعم التحقق من الصحة وأكثر — وكلها بإصدارات تحقق فريق إصدار Spring Boot أنها تعمل معًا.

السر في BOM. كل مشروع Spring Boot يرث من (أو يستورد) spring-boot-starter-parent، الذي يرث بدوره من spring-boot-dependencies — وهو Bill of Materials يثبّت إصدار كل مكتبة تُشحن مع Spring Boot. تُشير المبدئيات بعد ذلك إلى هذه الإصدارات دون تكرارها. لهذا السبب نادرًا ما تكتب أرقام إصدارات للـ starters في POM الخاص بك.

POM الأب وBOM

عند توليد مشروع من start.spring.io، يبدو pom.xml الناتج هكذا في أعلاه:

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.3.0</version> <relativePath/> </parent>

هذا الإعلان الواحد يمنحك: إصدارات تبعيات مُدارة لأكثر من 300 مكتبة، وإعدادات Maven plugin افتراضية معقولة (المُترجم لـ Java 17 أو أعلى، تصفية الموارد، إلخ)، والخاصية java.version جاهزة للتعديل. إذا كان مشروعك يمتلك بالفعل POM أبًا خاصًا به، يمكنك استخدام BOM باستيراده:

<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>3.3.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

أهم المبدئيات

يسرد القائمة أدناه المبدئيات التي ستلجأ إليها في كل مشروع تقريبًا. كل منها يضيف مجموعة مُركّزة ومتوافقة من المكتبات.

  • spring-boot-starter — المبدئي الأساسي. يُضمَّن تلقائيًا في جميع المبدئيات الأخرى. يُحضر Spring Core وSpring Context (حاوية IoC التي تعلمتها في درس Spring IoC) وتسجيل السجلات عبر Logback وبنية التهيئة التلقائية.
  • spring-boot-starter-web — Spring MVC وTomcat 10 المدمج وJackson لتسلسل JSON ومعالجة التعليقات التوضيحية @RestController/@RequestMapping التي تحتاجها لـ REST APIs.
  • spring-boot-starter-data-jpa — Hibernate 6 وSpring Data JPA (المستودعات و@Entity وJPQL) وبنية المعاملات. يتطلب مبدئي برنامج تشغيل JDBC أو حبة DataSource.
  • spring-boot-starter-security — Spring Security 6 مع إعدادات أمان HTTP معقولة افتراضيًا. كل نقطة نهاية محمية افتراضيًا؛ تُهيّئ قواعد الوصول في حبة SecurityFilterChain.
  • spring-boot-starter-validation — Hibernate Validator (التنفيذ المرجعي لـ Jakarta Bean Validation 3.0). يُفعّل @Valid و@NotNull و@Size وغيرها على معاملات أساليب المتحكم وكائنات المجال.
  • spring-boot-starter-test — JUnit 5 وMockito وAssertJ وSpring Test و@SpringBootTest. نطاقه test تلقائيًا فلا يتسرب شيء إلى الجزء الإنتاجي من المشروع.
  • spring-boot-starter-actuator — نقاط نهاية جاهزة للإنتاج (/actuator/health و/actuator/metrics والمعلومات والبيئة وغيرها) تتكامل مع أدوات المراقبة مثل Prometheus.
  • spring-boot-starter-cache — طبقة تجريد فوق مزودي التخزين المؤقت. أضف مزودًا مثل Caffeine أو Redis وسيُوصَل تلقائيًا.
  • spring-boot-starter-data-redis — Lettuce (عميل Redis غير المتزامن) ودعم Spring Data Redis template.
  • spring-boot-starter-amqp — تكامل RabbitMQ عبر Spring AMQP و@RabbitListener.

الإعلان عن المبدئيات في Maven

نظرًا لأن BOM الأب يدير الإصدارات، تُعلن عن المبدئيات دون وسم <version>:

<dependencies> <!-- REST API --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- JPA + برنامج تشغيل قاعدة البيانات --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> <!-- التحقق من صحة الحبوب --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <!-- الاختبارات (نطاق test فقط) --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>

استبدال التبعيات المتعدية أو استثناؤها

تختار المبدئيات إعدادًا افتراضيًا موجَّهًا بالرأي. أحيانًا تحتاج إلى شيء مختلف. على سبيل المثال، يستخدم spring-boot-starter-web Tomcat المدمج، لكنك قد تفضّل Undertow لإدخاله غير المتزامن أو بصمة ذاكرة أصغر. تستثني الإعداد الافتراضي وتضيف البديل:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <!-- إضافة Undertow بدلًا منه --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency>

يمكنك أيضًا تجاوز إصدار مُدار بضبط الخاصية المقابلة في POM. على سبيل المثال، لاستخدام إصدار Jackson أحدث:

<properties> <java.version>21</java.version> <jackson.version>2.17.1</jackson.version> </properties>
تجاوز الإصدارات بحذر. يمثّل BOM مصفوفة مُختبَرة. إذا أجبرت مكتبة على إصدار أحدث، قد تُدخل توافقات معطوبة مع مكتبات أخرى لم يختبرها فريق Spring Boot. شغّل دائمًا مجموعة الاختبارات الكاملة بعد أي تجاوز للإصدار، وتتبّع سبب التجاوز حتى تتمكن من إزالته عندما يصدر إصدار Boot التالي.

فحص شجرة التبعيات

بعد إضافة المبدئيات، شغّل شجرة تبعيات Maven لترى بالضبط ما جُلب واكتشاف أي تكرارات غير مرغوبة:

mvn dependency:tree

ابحث عن تسميات CONFLICT وomitted for conflict with — تُشير إلى أن مبدئيَّين سحبا إصدارات مختلفة من المكتبة ذاتها واختار Maven أحدهما. عادةً تختار قاعدة Maven "الأقرب يفوز" الإصدار الصحيح، لكنك أحيانًا تحتاج إلى الإعلان عن إصدار صريح في POM الخاص بك لإجبار اختيار معين.

استخدم mvn dependency:tree -Dincludes=groupId:artifactId لتصفية الشجرة إلى مكتبة محددة وتتبع أي مبدئي أدخلها بالضبط. هذا لا يُقدَّر بثمن عند تشخيص تعارضات مسار الفئات أو الاستيرادات المتعدية غير المتوقعة.

إنشاء Starter خاص بك (النمط)

إذا بنيت مكتبات داخلية تُستخدم عبر خدمات متعددة، يمكنك تغليفها كـ starters مخصصة باتباع اتفاقية Spring Boot: وحدة مكتبة باسم acme-spring-boot-autoconfigure وملف acme-spring-boot-starter رقيق اختياري يُعلن عنها فقط كتبعية. تُسجّل وحدة autoconfigure فئات التهيئة التلقائية في META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (آلية Spring Boot 3 التي حلّت محل ملف spring.factories القديم). هذا يتيح لأي مشروع يضع starter على مسار الفئات الحصول على حباتك مُوصَّلة تلقائيًا — بالطريقة ذاتها التي تعمل بها المبدئيات الرسمية.

الخلاصة

المبدئيات حزم تبعيات مُنتقاة مدعومة بـ Bill of Materials يضمن توافق الإصدارات. أعلن عن المبدئيات التي تحتاجها، دع BOM يدير الإصدارات، واستخدم <exclusions> وتجاوزات الخصائص عند الحاجة للانحراف عن الإعدادات الافتراضية. إن فهم هذا النموذج من التبعيات — لا مجرد معرفة أي مبدئي تختار — هو ما يُمكّنك من تشخيص مشاكل مسار الفئات وتقليص حجم القطعة الأثرية واتخاذ مقايضات مدروسة مع نمو تطبيقك.