انتقل إلى المحتوى الرئيسي

الفصل 2: هيكل مشروع Spring Boot

مقدمة​

يتبع مشروع Spring Boot هيكلًا موحدًا يعتمد على اتفاقيات Maven. يسهل هذا التنظيم التنقل في الكود ويسمح للمطورين بالعثور بسرعة على الملفات اللازمة.

أهداف الفصل​

في نهاية هذا الفصل، ستكون قادرًا على:

  • فهم تنظيم الدلائل في مشروع Spring Boot
  • تحديد دور كل ملف مهم
  • تنظيم الكود الخاص بك وفقًا لأفضل الممارسات
  • التنقل بفعالية في مشروع Spring Boot

نظرة عامة على الهيكل​

شجرة الدليل الكاملة​

greeting-app/
├── .mvn/ # Maven Wrapper
│ └── wrapper/
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── src/
│ ├── main/
│ │ ├── java/ # كود المصدر Java
│ │ │ └── com/example/greeting/
│ │ │ └── GreetingApplication.java
│ │ └── resources/ # موارد التطبيق
│ │ ├── static/ # ملفات ثابتة (CSS، JS، صور)
│ │ ├── templates/ # قوالب (Thymeleaf، Freemarker)
│ │ ├── application.properties # التكوين الرئيسي
│ │ └── application.yml # تكوين YAML (بديل)
│ └── test/
│ ├── java/ # اختبارات الوحدة والتكامل
│ │ └── com/example/greeting/
│ │ └── GreetingApplicationTests.java
│ └── resources/ # موارد الاختبار
│ └── application-test.properties
├── target/ # ملفات مجمعة (مولدة)
├── .gitignore # ملفات لتجاهلها بواسطة Git
├── mvnw # Maven wrapper (Unix/macOS)
├── mvnw.cmd # Maven wrapper (Windows)
├── pom.xml # تكوين Maven
├── HELP.md # وثائق مولدة
└── README.md # وثائق المشروع

الدليل الجذري​

1. ملف pom.xml​

الدور: ملف تكوين Maven (Project Object Model)

المحتوى الرئيسي:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<!-- Parent Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/>
</parent>

<!-- Identifiants du projet -->
<groupId>com.example</groupId>
<artifactId>greeting</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>greeting</name>
<description>تطبيق التحية</description>

<!-- Propriétés -->
<properties>
<java.version>17</java.version>
</properties>

<!-- Dépendances -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<!-- Plugin de build -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

الأقسام المهمة:

القسمالوصف
<parent>يرث تكوين Spring Boot
<groupId>, <artifactId>, <version>معرفات Maven للمشروع
<properties>تكوين عام (إصدار Java، الترميز، إلخ)
<dependencies>قائمة تبعيات المشروع
<build>تكوين عملية البناء

2. Maven Wrapper (mvnw, mvnw.cmd)​

الدور: يسمح بتشغيل Maven دون تثبيته عالميًا

المزايا:

  • ضمان إصدار Maven لجميع المطورين
  • لا حاجة لتثبيت Maven يدويًا
  • سكربتات مضمنة في المشروع

الاستخدام:

Linux/macOS:

./mvnw clean install
./mvnw spring-boot:run

Windows:

mvnw.cmd clean install
mvnw.cmd spring-boot:run

3. ملف .gitignore​

الدور: قائمة الملفات التي لا يجب تتبعها بواسطة Git

المحتوى النموذجي:

# Fichiers compilés
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/

# IDE
.idea/
*.iml
.vscode/
.classpath
.project
.settings/

# Système
.DS_Store
Thumbs.db

# Logs
*.log

# Fichiers temporaires
*.tmp
*.bak

الدليل src/main/java​

هيكل الحزم​

الاتفاقية: تنظيم الكود في طبقات وظيفية

src/main/java/com/example/greeting/
├── GreetingApplication.java # الفئة الرئيسية
├── controller/ # وحدات التحكم REST/MVC
│ ├── GreetingController.java
│ └── UserController.java
├── service/ # منطق الأعمال
│ ├── GreetingService.java
│ └── UserService.java
├── repository/ # الوصول إلى البيانات
│ ├── UserRepository.java
│ └── ProductRepository.java
├── model/ # الكيانات و DTOs
│ ├── entity/
│ │ ├── User.java
│ │ └── Product.java
│ └── dto/
│ ├── UserDTO.java
│ └── ProductDTO.java
├── config/ # تكوين Spring
│ ├── SecurityConfig.java
│ └── DatabaseConfig.java
├── exception/ # إدارة الأخطاء
│ ├── ResourceNotFoundException.java
│ └── GlobalExceptionHandler.java
└── util/ # فئات الأدوات
└── DateUtil.java

العمارة الطبقية​

مسؤوليات كل طبقة:

الطبقةالدورالتعليقات التوضيحية
Controllerإدارة طلبات HTTP@RestController, @Controller
Serviceمنطق الأعمال@Service
Repositoryالوصول إلى البيانات@Repository, واجهة JPA
Modelتمثيل البيانات@Entity, POJO

الفئة الرئيسية: GreetingApplication.java​

المحتوى:

package com.example.greeting;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GreetingApplication {

public static void main(String[] args) {
SpringApplication.run(GreetingApplication.class, args);
}
}

التعليق التوضيحي @SpringBootApplication:

هذا التعليق التوضيحي هو اختصار يجمع بين ثلاثة تعليقات توضيحية:

@SpringBootApplication
=
@SpringBootConfiguration // تكوين Spring
+ @EnableAutoConfiguration // التكوين التلقائي
+ @ComponentScan // مسح المكونات

دور كل تعليق توضيحي:


الدليل src/main/resources​

نظرة عامة​

src/main/resources/
├── static/ # ملفات ثابتة
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── script.js
│ └── images/
│ └── logo.png
├── templates/ # قوالب (Thymeleaf)
│ ├── index.html
│ └── user.html
├── application.properties # التكوين الرئيسي
├── application-dev.properties # تكوين التطوير
├── application-prod.properties # تكوين الإنتاج
├── application.yml # تكوين YAML (بديل)
├── banner.txt # لافتة مخصصة عند بدء التشغيل
└── data.sql # سكربت SQL للتهيئة

1. الدليل static/​

الدور: يحتوي على الملفات الثابتة التي يتم تقديمها مباشرة

أنواع الملفات:

  • CSS (أوراق الأنماط)
  • JavaScript (سكربتات جانب العميل)
  • الصور (PNG، JPG، SVG)
  • الخطوط (خطوط مخصصة)

الوصول:

http://localhost:8080/css/style.css
http://localhost:8080/js/script.js
http://localhost:8080/images/logo.png

الهيكل الموصى به:

static/
├── css/
├── js/
├── images/
├── fonts/
└── favicon.ico

2. الدليل templates/​

الدور: يحتوي على قوالب العرض (إذا كنت تستخدم محرك قوالب)

محركات القوالب المدعومة:

  • Thymeleaf (موصى به)
  • Freemarker
  • Mustache
  • Groovy Templates

مثال Thymeleaf:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>تحية</title>
</head>
<body>
<h1 th:text="${message}">الرسالة الافتراضية</h1>
</body>
</html>

3. ملف application.properties​

الدور: التكوين الرئيسي للتطبيق

الصيغة: key=value

أمثلة على التكوينات:

# منفذ الخادم
server.port=8080

# اسم التطبيق
spring.application.name=greeting-app

# تكوين قاعدة البيانات
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=postgres
spring.datasource.password=secret

# JPA/Hibernate
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

# السجلات
logging.level.root=INFO
logging.level.com.example=DEBUG

# تنسيق التواريخ
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=America/Montreal

4. ملف application.yml (بديل)​

الدور: نفس دور application.properties ولكن بصيغة YAML

الصيغة: هرمية مع المسافات البادئة

مثال مكافئ:

server:
port: 8080

spring:
application:
name: greeting-app

datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: secret

jpa:
hibernate:
ddl-auto: update
show-sql: true

logging:
level:
root: INFO
com.example: DEBUG

المقارنة:

الصيغةالمزاياالعيوب
propertiesبسيط، مألوفمتكرر للهياكل المعقدة
ymlقابل للقراءة، هرميحساس للمسافات البادئة

5. ملفات التكوين​

المفهوم: تكوينات مختلفة حسب البيئة

ملفات التكوين:

application.properties           # التكوين الافتراضي
application-dev.properties # التطوير
application-test.properties # الاختبارات
application-prod.properties # الإنتاج

تفعيل التكوين:

عبر application.properties:

spring.profiles.active=dev

عبر سطر الأوامر:

java -jar app.jar --spring.profiles.active=prod

عبر متغير البيئة:

export SPRING_PROFILES_ACTIVE=prod

مثال على التكوين حسب البيئة:

application-dev.properties:

server.port=8080
spring.datasource.url=jdbc:h2:mem:testdb
logging.level.root=DEBUG

application-prod.properties:

server.port=80
spring.datasource.url=jdbc:postgresql://prod-server:5432/mydb
logging.level.root=WARN

الدليل src/test/java​

هيكل الاختبارات​

src/test/java/com/example/greeting/
├── GreetingApplicationTests.java # اختبار بدء التشغيل
├── controller/
│ └── GreetingControllerTest.java # اختبارات وحدة التحكم
├── service/
│ └── GreetingServiceTest.java # اختبارات الخدمة
└── repository/
└── UserRepositoryTest.java # اختبارات المستودع

اختبار بدء التشغيل الافتراضي​

package com.example.greeting;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class GreetingApplicationTests {

@Test
void contextLoads() {
// التحقق من تحميل سياق Spring بشكل صحيح
}
}

الدور: التحقق من بدء التطبيق دون أخطاء


الدليل target/​

الدور: يحتوي على الملفات المجمعة و JAR النهائي

مولد بواسطة: Maven أثناء البناء

المحتوى:

target/
├── classes/ # فئات مجمعة (.class)
├── test-classes/ # اختبارات مجمعة
├── generated-sources/ # مصادر مولدة
├── maven-status/ # حالة Maven
└── greeting-0.0.1-SNAPSHOT.jar # JAR نهائي قابل للتنفيذ

مهم: يتم تجاهل هذا الدليل بواسطة Git (في .gitignore)

التنظيف:

mvn clean

التنظيم حسب الوظيفة مقابل حسب الطبقة​

النهج 1: حسب الطبقة (موصى به للمشاريع الصغيرة)​

com.example.greeting/
├── controller/
│ ├── UserController.java
│ └── ProductController.java
├── service/
│ ├── UserService.java
│ └── ProductService.java
├── repository/
│ ├── UserRepository.java
│ └── ProductRepository.java
└── model/
├── User.java
└── Product.java

المزايا:

  • بسيط وواضح
  • سهل الفهم للمبتدئين
  • معيار Spring Boot

العيوب:

  • صعب التوسع للمشاريع الكبيرة
  • ترابط بين الوظائف

النهج 2: حسب الوظيفة (موصى به للمشاريع الكبيرة)​

com.example.greeting/
├── user/
│ ├── UserController.java
│ ├── UserService.java
│ ├── UserRepository.java
│ └── User.java
├── product/
│ ├── ProductController.java
│ ├── ProductService.java
│ ├── ProductRepository.java
│ └── Product.java
└── order/
├── OrderController.java
├── OrderService.java
├── OrderRepository.java
└── Order.java

المزايا:

  • تماسك عالي
  • ترابط منخفض
  • يسهل الانتقال إلى بنية الخدمات المصغرة

العيوب:

  • أقل معيارية
  • قد يكون مربكًا في البداية

اتفاقيات التسمية​

الحزم​

الاتفاقية: جميعها بأحرف صغيرة، الكلمات مفصولة بنقاط

com.example.greeting           // ✅ جيد
com.example.greeting.service // ✅ جيد
com.Example.Greeting // ❌ سيء (أحرف كبيرة)
com.example.greeting_service // ❌ سيء (شرطة سفلية)

الفئات​

الاتفاقية: PascalCase (الحرف الأول من كل كلمة كبير)

UserController        // ✅ جيد
GreetingService // ✅ جيد
userController // ❌ سيء (يبدأ بحرف صغير)
user_controller // ❌ سيء (شرطة سفلية)

اللاحقات الموصى بها:

النوعاللاحقةالمثال
وحدة التحكمControllerUserController
الخدمةServiceUserService
المستودعRepositoryUserRepository
الكيانلا يوجدUser, Product
DTODTOUserDTO, CreateUserDTO
الاستثناءExceptionResourceNotFoundException
التكوينConfigSecurityConfig

الطرق​

الاتفاقية: camelCase (الحرف الأول صغير)

getUserById()         // ✅ جيد
findAllUsers() // ✅ جيد
GetUserById() // ❌ سيء (يبدأ بحرف كبير)
get_user_by_id() // ❌ سيء (شرطة سفلية)

المتغيرات والسمات​

الاتفاقية: camelCase

String userName;      // ✅ جيد
int userId; // ✅ جيد
String UserName; // ❌ سيء (يبدأ بحرف كبير)
String user_name; // ❌ سيء (شرطة سفلية)

الثوابت​

الاتفاقية: SCREAMING_SNAKE_CASE (جميعها بأحرف كبيرة، شرطات سفلية)

public static final int MAX_USERS = 100;              // ✅ جيد
public static final String API_BASE_URL = "/api/v1"; // ✅ جيد
public static final int maxUsers = 100; // ❌ سيء (camelCase)

تمارين عملية​

التمرين 1: استكشاف الهيكل​

الهدف: التعرف على هيكل المشروع

التعليمات:

  1. أنشئ مشروعًا باستخدام Spring Initializr (Spring Web فقط)
  2. استورده في VS Code
  3. حدد:
    • ملف pom.xml
    • الفئة الرئيسية
    • ملف application.properties
    • دليل الاختبارات
  4. ارسم شجرة الدليل على الورق

التمرين 2: إنشاء هيكل الحزم​

الهدف: تنظيم الكود في طبقات

التعليمات:

  1. في المشروع السابق، أنشئ الهيكل:
    com.example.demo/
    ├── controller/
    ├── service/
    ├── repository/
    └── model/
  2. أنشئ فئات فارغة في كل حزمة
  3. تحقق من الترجمة

التمرين 3: تكوين الملفات​

الهدف: إنشاء تكوينات حسب البيئة

التعليمات:

  1. أنشئ application-dev.properties:
    server.port=8080
    logging.level.root=DEBUG
  2. أنشئ application-prod.properties:
    server.port=80
    logging.level.root=WARN
  3. اختبر تفعيل كل تكوين

أسئلة مراجعة​

  1. أي ملف يحتوي على تبعيات Maven؟

  2. ما هو دور الدليل target/؟

  3. ما الفرق بين static/ و templates/؟

  4. ماذا يحتوي التعليق التوضيحي @SpringBootApplication؟

  5. كيف تسمي ملف تكوين لبيئة التطوير؟

  6. ما هي اتفاقية التسمية لفئات وحدة التحكم؟

  7. أين تضع ملفات CSS و JavaScript؟

  8. ما الفرق بين application.properties و application.yml؟


ملخص الفصل​

النقاط الرئيسية​

  • يتبع هيكل Spring Boot اتفاقيات Maven
  • الكود المصدر في src/main/java
  • الموارد في src/main/resources
  • التنظيم في طبقات: Controller → Service → Repository
  • الاختبارات في src/test/java
  • تستخدم ملفات التكوين ملفات التكوين

أفضل الممارسات​

  • احترام اتفاقيات التسمية في Java
  • تنظيم الكود في حزم منطقية
  • فصل التكوينات حسب البيئة
  • استخدام لاحقات وصفية للفئات
  • تعليق الكود المعقد
  • الحفاظ على هيكل واضح ومتسق

الخطوات التالية​

في الفصل التالي، سنتعمق في:

الفصل 3: التكوين باستخدام application.properties

  • خصائص Spring Boot المتاحة
  • تكوين قاعدة البيانات
  • تكوين السجلات
  • خصائص مخصصة

العودة إلى الوحدة 2