404 Not Found

404 Not Found


nginx

كيف تعمل التهيئة التلقائية في Spring Boot

التهيئة التلقائية هي قلب Spring Boot—فهي تُسجل Beans تلقائياً بناءً على الأصناف الموجودة في مسار الأصناف، مما يتيح لك اتباع مبدأ "الاصطلاح على التهيئة".

1. ما ستتعلمه


2. قصة حقيقية من مطوّر إطار عمل

(1) نقطة الألم: الاضطرار لكتابة مجموعة من إعدادات التهيئة في كل عملية تكامل

يحتاج فريق Alice إلى دمج SDK دفع جديد في OrderFlow. في كل مرة يدمجون مكوناً جديداً، يجب عليهم كتابة صنف @Configuration، والإعلان عن Beans، وتهيئة الخصائص، والتعامل مع التحميل الشرطي. يعمل Bob، أحد أعضاء الفريق، حتى وقت متأخر من الليل بسبب تعارضات Beans والتبعيات الدائرية؛ استغرق تكامل Redis وحده ثلاثة أيام.

(2) حلول التهيئة التلقائية

Spring Boot Starter يُبسّط "دمج مكون" إلى "إضافة تبعية":

XML
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

بمجرد إضافة هذه التبعية، يتم تهيئة كل من مصنع اتصال Redis وRedisTemplate تلقائياً.

(3) العوائد

بعد أن أنشأت Alice الـ Starter المخصص لـ OrderFlow، يمكن للأعضاء الجدد في الفريق دمج SDK الدفع بمجرد إضافة تبعية واحدة—لم تعد هناك حاجة لتهيئة أي Beans يدوياً، وانخفض وقت التكامل من 3 أيام إلى 30 دقيقة.


3. آلية تحميل التهيئة التلقائية

(1) من @EnableAutoConfiguration إلى AutoConfiguration.imports

100%
flowchart LR
    A["@EnableAutoConfiguration"] --> B["استيراد<br/>AutoConfigurationImportSelector"]
    B --> C["قراءة<br/>META-INF/spring/<br/>AutoConfiguration.imports"]
    C --> D["تصفية عبر<br/>@Conditional<br/>التعليقات"]
    D --> E["تسجيل<br/>أصناف التهيئة التلقائية<br/>المؤهلة"]
الإصدار ملف التحميل التنسيق
Spring Boot 2.x META-INF/spring.factories key=class1,class2
Spring Boot 3.x META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports اسم صنف مؤهل بالكامل في كل سطر
📌 نقطة رئيسية: Spring Boot 3.x يستخدم ملف AutoConfiguration.imports الجديد ولم يعد يستخدم spring.factories لتسجيل التهيئة التلقائية.

(2) طبيعة أصناف التهيئة التلقائية

صنف التهيئة التلقائية هو صنف @Configuration مع تعليقات شرطية:

(1) ▶ مثال: تبسيط الكود المصدري لتهيئة DataSource التلقائية

JAVA
@AutoConfiguration
@ConditionalOnClass(DataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {

    @Bean
    @ConfigurationProperties("spring.datasource")
    public DataSource dataSource(DataSourceProperties properties) {
        return DataSourceBuilder.create()
            .url(properties.getUrl())
            .username(properties.getUsername())
            .password(properties.getPassword())
            .build();
    }
}

الناتج:

TEXT
// التنفيذ ناجح

4. شرح مفصل للتعليقات الشرطية

(1) تعليقات الشرط الأساسية

التعليق الشرط التطبيقات النموذجية
@ConditionalOnClass الصنف المحدد موجود في مسار الأصناف يسري فقط بعد تضمين التبعية
@ConditionalOnMissingClass الصنف غير موجود في مسار الأصناف توفير بديل عند غياب التبعية
@ConditionalOnBean Bean محدد موجود في الحاوية يُستخدم عند الاعتماد على Beans أخرى
@ConditionalOnMissingBean Bean المحدد غير موجود في الحاوية توفير Bean افتراضي؛ التنحي لتعريفات المستخدم عند توفرها
@ConditionalOnProperty خصائص التهيئة تفي بالشروط التحكم في الوظائف عبر مفاتيح التهيئة

(1) ▶ مثال: التحكم بمفتاح @ConditionalOnProperty

JAVA
@Configuration
@ConditionalOnProperty(
    prefix = "orderflow.notification",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = false
)
public class NotificationConfig {

    @Bean
    public NotificationService emailNotificationService() {
        return new EmailNotificationService();
    }
}

الناتج:

TEXT
// التنفيذ ناجح
YAML
orderflow:
  notification:
    enabled: true   # اضبط false لتعطيل الإشعارات

(2) ▶ مثال: @ConditionalOnMissingBean يوفر تنفيذاً افتراضياً

JAVA
@Configuration
public class OrderFlowAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean(IdGenerator.class)
    public IdGenerator uuidIdGenerator() {
        return new UuidIdGenerator();
    }

    @Bean
    @ConditionalOnMissingBean(OrderNumberGenerator.class)
    @ConditionalOnProperty(
        prefix = "orderflow.order",
        name = "number-prefix",
        havingValue = "ORD",
        matchIfMissing = true
    )
    public OrderNumberGenerator defaultOrderNumberGenerator() {
        return new SequentialOrderNumberGenerator("ORD");
    }
}

الناتج:

TEXT
// التنفيذ ناجح

5. Starter مخصص

(1) اصطلاحات تسمية Starter

النوع اصطلاح التسمية مثال
Starter رسمي spring-boot-starter-* spring-boot-starter-web
Starter طرف ثالث *-spring-boot-starter orderflow-spring-boot-starter

(2) هيكل مشروع Starter

TEXT
orderflow-spring-boot-starter/
├── src/main/
│   ├── java/com/orderflow/autoconfigure/
│   │   ├── OrderFlowAutoConfiguration.java
│   │   └── OrderFlowProperties.java
│   └── resources/
│       └── META-INF/spring/
│           └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
└── pom.xml

(1) ▶ مثال: الكود الكامل لـ Starter مخصص

JAVA
// OrderFlowProperties.java
@ConfigurationProperties(prefix = "orderflow.notification")
public record OrderFlowNotificationProperties(
    boolean enabled,
    String fromEmail,
    String templatePath
) {}

// OrderFlowAutoConfiguration.java
@AutoConfiguration
@ConditionalOnClass(JavaMailSender.class)
@ConditionalOnProperty(
    prefix = "orderflow.notification",
    name = "enabled",
    havingValue = "true"
)
@EnableConfigurationProperties(OrderFlowNotificationProperties.class)
public class OrderFlowAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean(NotificationService.class)
    public NotificationService notificationService(
            OrderFlowNotificationProperties props) {
        return new EmailNotificationService(
            props.fromEmail(),
            props.templatePath()
        );
    }
}

الناتج:

TEXT
التنفيذ ناجح
TEXT
# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.orderflow.autoconfigure.OrderFlowAutoConfiguration

6. تصحيح أخطاء التهيئة التلقائية واستكشافها

(1) وضع --debug

عند إضافة معامل --debug عند التشغيل، يُخرج Spring Boot تقرير تهيئة تلقائية:

BASH
java -jar orderflow-service.jar --debug

(1) ▶ مثال: تفسير تقرير التهيئة التلقائية

TEXT
============================
CONDITIONS EVALUATION REPORT
============================

Positive matches:
-----------------
   DataSourceAutoConfiguration matched:
      - @ConditionalOnClass found required class 'javax.sql.DataSource'

Negative matches:
-----------------
   ActiveMQAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory'

Exclusions:
-----------
   None

Unconditional classes:
----------------------
   org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration

الناتج:

TEXT
التنفيذ ناجح
قسم التقرير المعنى
Positive matches تهيئات تلقائية تفي بالشروط ونشطة
Negative matches تهيئات تلقائية لا تفي بالشروط وغير سارية
Exclusions تهيئات تلقائية مستبعدة صراحةً
Unconditional Classes تهيئة تلقائية للتسجيل غير المشروط

(2) استبعاد التهيئة التلقائية

(2) ▶ مثال: استبعاد التهيئات التلقائية غير المرغوب فيها

JAVA
// الطريقة 1: الاستبعاد بالتعليق
@SpringBootApplication(exclude = {
    DataSourceAutoConfiguration.class,
    HibernateJpaAutoConfiguration.class
})
public class OrderFlowApplication { ... }

// الطريقة 2: خاصية التهيئة
// application.yml
spring:
  autoconfigure:
    exclude:
      - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

الناتج:

TEXT
// التنفيذ ناجح
طريقة الاستبعاد السيناريوهات المناسبة المرونة
@SpringBootApplication(exclude) استبعاد دائم محدد وقت الترجمة
spring.autoconfigure.exclude استبعاد حسب البيئة متغير وقت التشغيل
@ConditionalOnProperty استبعاد حسب الشرط الأكثر مرونة

7. مثال شامل: التنفيذ الكامل لـ OrderFlow Notification Starter

JAVA
// orderflow-notification-spring-boot-starter

// OrderFlowNotificationProperties.java
package com.orderflow.autoconfigure;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "orderflow.notification")
public record OrderFlowNotificationProperties(
    boolean enabled,
    String fromEmail,
    String templatePath,
    SmtpConfig smtp
) {
    public record SmtpConfig(String host, int port, boolean ssl) {}
}

// NotificationService.java
package com.orderflow.autoconfigure;

public interface NotificationService {
    void send(String to, String subject, String body);
}

// EmailNotificationService.java
package com.orderflow.autoconfigure;

public class EmailNotificationService implements NotificationService {
    private final String fromEmail;
    private final String templatePath;

    public EmailNotificationService(String fromEmail, String templatePath) {
        this.fromEmail = fromEmail;
        this.templatePath = templatePath;
    }

    @Override
    public void send(String to, String subject, String body) {
        // منطق إرسال البريد الإلكتروني
        System.out.printf("Send to %s: [%s] %s%n", to, subject, body);
    }
}

// OrderFlowNotificationAutoConfiguration.java
package com.orderflow.autoconfigure;

import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

@AutoConfiguration
@ConditionalOnClass(name = "org.springframework.mail.javamail.JavaMailSender")
@ConditionalOnProperty(prefix = "orderflow.notification", name = "enabled", havingValue = "true")
@EnableConfigurationProperties(OrderFlowNotificationProperties.class)
public class OrderFlowNotificationAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean(NotificationService.class)
    public NotificationService notificationService(OrderFlowNotificationProperties props) {
        return new EmailNotificationService(props.fromEmail(), props.templatePath());
    }
}
TEXT
# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.orderflow.autoconfigure.OrderFlowNotificationAutoConfiguration

❓ أسئلة شائعة

س هل تتعارض التهيئة التلقائية مع التهيئة اليدوية؟
ج لا. أصناف التهيئة التلقائية تستخدم @ConditionalOnMissingBean بكثرة. إذا عرّفت يدوياً Bean من نفس النوع، فإن التهيئة التلقائية تتنحى تلقائياً. هذا هو مبدأ "أسبقية تعريف المستخدم".
س لماذا لا تسري تهيئتي التلقائية؟
ج الأسباب الشائعة: 1) صنف تبعية مفقود من مسار الأصناف؛ 2) شرط @ConditionalOnProperty غير متحقق؛ 3) مسار أو محتوى ملف AutoConfiguration.imports غير صحيح؛ 4) صنف التهيئة التلقائية خارج نطاق مسح المكونات (لكن التهيئة التلقائية تُحمّل عبر ملف imports ولا تتطلب المسح).
س هل لا يزال بالإمكان استخدام spring.factories؟
ج Spring Boot 3.x لا يزال يدعم spring.factories للتوافق مع الإصدارات السابقة، لكن يجب إعطاء الأولوية لاستخدام ملفات AutoConfiguration.imports لتسجيل التهيئة التلقائية. سيتم إزالة spring.factories في الإصدارات المستقبلية.
س كم عدد الوحدات التي يحتاجها Starter المخصص؟
ج عادة وحدتان: 1) وحدة autoconfigure (كود التهيئة التلقائية)؛ 2) وحدة starter (pom.xml الذي يجمع التبعيات). في المشاريع البسيطة، يمكن دمجها في وحدة واحدة.
س كيف يمكنني معرفة أي تهيئات تلقائية نشطة حالياً؟
ج 1) شغّل التطبيق بالمعامل --debug لعرض التقرير؛ 2) تحقق من نقطة النهاية /actuator/conditions في Actuator؛ 3) ابحث عن ملف AutoConfiguration.imports في IDE.
س ما هي مخاطر استبعاد التهيئة التلقائية؟
ج بمجرد الاستبعاد، ستصبح الميزات ذات الصلة غير متاحة، وقد تفشل التهيئات التلقائية الأخرى التي تعتمد عليها. تأكد من فهم آثار الاستبعاد؛ يمكنك التحقق من سلسلة التبعية باستخدام تقارير التصحيح.

📖 ملخص


📝 تمارين

  1. تمرين أساسي (الصعوبة ⭐): شغّل مشروع OrderFlow باستخدام وضع --debug، اسرد جميع أصناف التهيئة التلقائية ضمن "Positive matches"، وافهم شروط مسار الأصناف المطلوبة لكل تهيئة تلقائية.

  2. تمرين متقدم (الصعوبة: ⭐⭐): أنشئ orderflow-spring-boot-starter يتضمن ميزة إشعارات تُتحكم بها بمفتاح @ConditionalOnProperty، ثم ادمجه في مشروع OrderFlow واختبره.

  3. تحدٍ (الصعوبة: ⭐⭐⭐): نفّذ نظام تهيئة تلقائية يدعم تطبيقات متعددة—استخدم إشعارات Kafka إذا كان Kafka موجوداً في مسار الأصناف، وإشعارات البريد الإلكتروني غير ذلك، وإشعارات السجل إذا لم يكن أي منهما متاحاً. فكّر في أولوية التعليقات الشرطية وتصميم الاستبعاد المتبادل.

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%