الفصل 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 // ❌ سيء (شرطة سفلية)
اللاحقات الموصى بها:
| النوع | اللاحقة | المثال |
|---|---|---|
| وحدة التحكم | Controller | UserController |
| الخدمة | Service | UserService |
| المستودع | Repository | UserRepository |
| الكيان | لا يوجد | User, Product |
| DTO | DTO | UserDTO, CreateUserDTO |
| الاستثناء | Exception | ResourceNotFoundException |
| التكوين | Config | SecurityConfig |
الطرق
الاتفاقية: 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: استكشاف الهيكل
الهدف: التعرف على هيكل المشروع
التعليمات:
- أنشئ مشروعًا باستخدام Spring Initializr (Spring Web فقط)
- استورده في VS Code
- حدد:
- ملف pom.xml
- الفئة الرئيسية
- ملف application.properties
- دليل الاختبارات
- ارسم شجرة الدليل على الورق
التمرين 2: إنشاء هيكل الحزم
الهدف: تنظيم الكود في طبقات
التعليمات:
- في المشروع السابق، أنشئ الهيكل:
com.example.demo/
├── controller/
├── service/
├── repository/
└── model/ - أنشئ فئات فارغة في كل حزمة
- تحقق من الترجمة
التمرين 3: تكوين الملفات
الهدف: إنشاء تكوينات حسب البيئة
التعليمات:
- أنشئ
application-dev.properties:server.port=8080
logging.level.root=DEBUG - أنشئ
application-prod.properties:server.port=80
logging.level.root=WARN - اختبر تفعيل كل تكوين
أسئلة مراجعة
-
أي ملف يحتوي على تبعيات Maven؟
-
ما هو دور الدليل
target/؟ -
ما الفرق بين
static/وtemplates/؟ -
ماذا يحتوي التعليق التوضيحي
@SpringBootApplication؟ -
كيف تسمي ملف تكوين لبيئة التطوير؟
-
ما هي اتفاقية التسمية لفئات وحدة التحكم؟
-
أين تضع ملفات CSS و JavaScript؟
-
ما الفرق بين
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 المتاحة
- تكوين قاعدة البيانات
- تكوين السجلات
- خصائص مخصصة