الفصل 3: التكوين باستخدام application.properties و application.yml
المقدمة
التكوين هو جانب أساسي من أي تطبيق. يوفر Spring Boot نظام تكوين قوي ومرن يسمح بتخصيص سلوك التطبيق دون تعديل الكود.
أهداف الفصل
في نهاية هذا الفصل، ستكون قادرًا على:
- تكوين تطبيق باستخدام application.properties و application.yml
- استخدام خصائص Spring Boot المحددة مسبقًا
- إنشاء خصائص مخصصة
- إدارة البيئات المختلفة باستخدام ملفات التعريف
- توسيع التكوين
ملفات التكوين
الموقع
يبحث Spring Boot عن ملفات التكوين بالترتيب التالي:
ترتيب الأولوية (من الأعلى إلى الأدنى):
file:./config/application.propertiesfile:./config/application.ymlfile:./application.propertiesfile:./application.ymlclasspath:/config/application.propertiesclasspath:/config/application.ymlclasspath:/application.propertiesclasspath:/application.yml
في الممارسة العملية: ضع ملفاتك في src/main/resources/
تنسيق application.properties
بناء الجملة الأساسي
التنسيق:
cle=valeur
الخصائص:
- تنسيق بسيط للزوج المفتاح-القيمة
- لا يوجد مسافة بادئة
- تعليقات مع
# - تكرار البادئات
مثال كامل
# تكوين الخادم
server.port=8080
server.servlet.context-path=/api
# اسم التطبيق
spring.application.name=greeting-app
# تكوين قاعدة البيانات
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=postgres
spring.datasource.password=secret
spring.datasource.driver-class-name=org.postgresql.Driver
# تكوين JPA
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
# تكوين السجلات
logging.level.root=INFO
logging.level.com.example=DEBUG
logging.level.org.springframework.web=DEBUG
logging.file.name=logs/application.log
# تكوين Jackson (JSON)
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=America/Montreal
spring.jackson.serialization.indent-output=true
المزايا والعيوب
المزايا:
- تنسيق بسيط ومعروف على نطاق واسع
- متوافق مع Java Properties
- لا توجد تبعية خارجية
العيوب:
- متكرر للهياكل الهرمية
- أقل قابلية للقراءة للتكوينات المعقدة
تنسيق application.yml
بناء الجملة الأساسي
التنسيق: YAML (YAML Ain't Markup Language)
الخصائص:
- تنسيق هرمي مع مسافة بادئة
- المسافة البادئة = 2 أو 4 مسافات (بدون علامات تبويب)
- هيكل شجري
- أكثر إيجازًا
مثال كامل
# تكوين الخادم
server:
port: 8080
servlet:
context-path: /api
# اسم التطبيق
spring:
application:
name: greeting-app
# تكوين قاعدة البيانات
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: secret
driver-class-name: org.postgresql.Driver
# تكوين JPA
jpa:
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate:
format_sql: true
dialect: org.hibernate.dialect.PostgreSQLDialect
# تكوين Jackson
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: America/Montreal
serialization:
indent-output: true
# تكوين السجلات
logging:
level:
root: INFO
com.example: DEBUG
org.springframework.web: DEBUG
file:
name: logs/application.log
المزايا والعيوب
المزايا:
- أكثر قابلية للقراءة للهياكل المعقدة
- أقل تكرارًا
- دعم القوائم والخرائط
- تنسيق حديث
العيوب:
- حساس للمسافة البادئة
- أخطاء بناء الجملة أكثر شيوعًا
- يتطلب تبعية SnakeYAML (مضمنة افتراضيًا)
مقارنة properties مقابل yml
نفس التكوين في كلا التنسيقين
application.properties:
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=postgres
spring.datasource.password=secret
application.yml:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: secret
جدول المقارنة
| المعيار | properties | yml |
|---|---|---|
| قابلية القراءة | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| البساطة | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| الهيكل | مسطح | هرمي |
| التكرار | كثير | قليل |
| القوائم | صعب | سهل |
| التوافق | عالمي | يتطلب محلل |
| الأخطاء | نادرة | المسافة البادئة |
التوصية: استخدم .yml للتكوينات المعقدة، .properties للتكوينات البسيطة.
خصائص Spring Boot الشائعة
1. تكوين الخادم
server:
port: 8080 # منفذ الخادم
servlet:
context-path: /api # مسار الأساس
compression:
enabled: true # ضغط GZIP
error:
include-message: always # تضمين رسائل الخطأ
2. تكوين قاعدة البيانات
PostgreSQL
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: secret
driver-class-name: org.postgresql.Driver
MySQL
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: secret
driver-class-name: com.mysql.cj.jdbc.Driver
H2 (قاعدة بيانات في الذاكرة - اختبارات)
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
h2:
console:
enabled: true # وحدة تحكم H2 قابلة للوصول
path: /h2-console
3. تكوين JPA/Hibernate
spring:
jpa:
hibernate:
ddl-auto: update # none, validate, update, create, create-drop
show-sql: true # عرض استعلامات SQL
properties:
hibernate:
format_sql: true # تنسيق الاستعلامات
dialect: org.hibernate.dialect.PostgreSQLDialect
use_sql_comments: true # تعليق الاستعلامات
قيم ddl-auto:
| القيمة | الوصف | الاستخدام |
|---|---|---|
| none | لا يوجد إجراء | الإنتاج |
| validate | التحقق من صحة المخطط فقط | الإنتاج |
| update | تحديث المخطط | التطوير |
| create | إنشاء المخطط عند بدء التشغيل | الاختبارات |
| create-drop | إنشاء ثم حذف | الاختبارات |
4. تكوين السجلات
logging:
level:
root: INFO # المستوى العام
com.example: DEBUG # تطبيقك
org.springframework.web: DEBUG # Spring Web
org.hibernate.SQL: DEBUG # استعلامات SQL
org.hibernate.type: TRACE # معلمات SQL
pattern:
console: '%d{yyyy-MM-dd HH:mm:ss} - %msg%n'
file:
name: logs/application.log # ملف السجل
max-size: 10MB # الحجم الأقصى لكل ملف
مستويات السجل:
TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
5. تكوين Jackson (JSON)
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: America/Montreal
serialization:
indent-output: true # JSON مدمج
write-dates-as-timestamps: false
deserialization:
fail-on-unknown-properties: false
6. تكوين DevTools
spring:
devtools:
restart:
enabled: true # إعادة التشغيل التلقائي
livereload:
enabled: true # إعادة تحميل المتصفح
خصائص مخصصة
إنشاء خصائص مخصصة
application.yml:
app:
name: Greeting Application
version: 1.0.0
admin:
email: admin@example.com
phone: +1-514-123-4567
security:
jwt-secret: mySecretKey123
jwt-expiration: 86400000 # 24 ساعة بالمللي ثانية
الحقن باستخدام @Value
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AppConfig {
@Value("${app.name}")
private String appName;
@Value("${app.version}")
private String appVersion;
@Value("${app.admin.email}")
private String adminEmail;
public void printConfig() {
System.out.println("Application: " + appName);
System.out.println("Version: " + appVersion);
System.out.println("Admin Email: " + adminEmail);
}
}
فئة التكوين باستخدام @ConfigurationProperties
النهج الموصى به للعديد من الخصائص:
application.yml:
app:
security:
jwt-secret: mySecretKey123
jwt-expiration: 86400000
allowed-origins:
- http://localhost:3000
- http://localhost:4200
فئة التكوين:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@ConfigurationProperties(prefix = "app.security")
public class SecurityProperties {
private String jwtSecret;
private Long jwtExpiration;
private List<String> allowedOrigins;
// Getters et Setters
public String getJwtSecret() {
return jwtSecret;
}
public void setJwtSecret(String jwtSecret) {
this.jwtSecret = jwtSecret;
}
public Long getJwtExpiration() {
return jwtExpiration;
}
public void setJwtExpiration(Long jwtExpiration) {
this.jwtExpiration = jwtExpiration;
}
public List<String> getAllowedOrigins() {
return allowedOrigins;
}
public void setAllowedOrigins(List<String> allowedOrigins) {
this.allowedOrigins = allowedOrigins;
}
}
الاستخدام:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AuthService {
@Autowired
private SecurityProperties securityProperties;
public void generateToken() {
String secret = securityProperties.getJwtSecret();
Long expiration = securityProperties.getJwtExpiration();
// Logique de génération de token
}
}
إدارة ملفات التعريف
مفهوم ملفات التعريف
تسمح ملفات التعريف بوجود تكوينات مختلفة حسب البيئة.
إنشاء ملفات التعريف
هيكل الملفات:
src/main/resources/
├── application.yml # التكوين المشترك
├── application-dev.yml # التطوير
├── application-test.yml # الاختبارات
└── application-prod.yml # الإنتاج
التكوين حسب ملف التعريف
application.yml (مشترك):
spring:
application:
name: greeting-app
app:
name: Greeting Application
application-dev.yml:
server:
port: 8080
spring:
datasource:
url: jdbc:h2:mem:testdb
h2:
console:
enabled: true
logging:
level:
root: DEBUG
application-test.yml:
server:
port: 8081
spring:
datasource:
url: jdbc:h2:mem:testdb
logging:
level:
root: INFO
application-prod.yml:
server:
port: 80
spring:
datasource:
url: jdbc:postgresql://prod-db.example.com:5432/mydb
username: ${DB_USERNAME} # متغير البيئة
password: ${DB_PASSWORD}
logging:
level:
root: WARN
file:
name: /var/log/app/application.log
تفعيل ملف شخصي
الطريقة 1: في application.yml
spring:
profiles:
active: dev
الطريقة 2: سطر الأوامر
java -jar app.jar --spring.profiles.active=prod
الطريقة 3: متغير البيئة
export SPRING_PROFILES_ACTIVE=prod
java -jar app.jar
الطريقة 4: في IDE
VS Code (launch.json):
{
"configurations": [
{
"type": "java",
"name": "Spring Boot App",
"request": "launch",
"mainClass": "com.example.greeting.GreetingApplication",
"args": "--spring.profiles.active=dev"
}
]
}
ملفات شخصية متعددة
يمكنك تفعيل ملفات شخصية متعددة:
java -jar app.jar --spring.profiles.active=dev,local
ترتيب الأولوية: ملف التعريف الأخير له الأولوية
متغيرات البيئة
الاستخدام
يمكن لـ Spring Boot قراءة متغيرات البيئة:
application.yml:
spring:
datasource:
url: ${DATABASE_URL:jdbc:postgresql://localhost:5432/mydb}
username: ${DATABASE_USER:postgres}
password: ${DATABASE_PASSWORD:secret}
بناء الجملة: ${NOM_VARIABLE:valeur_par_defaut}
تعيين المتغيرات
Windows (CMD):
set DATABASE_URL=jdbc:postgresql://prod-server:5432/mydb
set DATABASE_USER=admin
set DATABASE_PASSWORD=supersecret
java -jar app.jar
Windows (PowerShell):
$env:DATABASE_URL="jdbc:postgresql://prod-server:5432/mydb"
$env:DATABASE_USER="admin"
$env:DATABASE_PASSWORD="supersecret"
java -jar app.jar
Linux/macOS:
export DATABASE_URL=jdbc:postgresql://prod-server:5432/mydb
export DATABASE_USER=admin
export DATABASE_PASSWORD=supersecret
java -jar app.jar
التكوين الخارجي
ملف تكوين خارجي
يمكن لـ Spring Boot تحميل ملفات تكوين خارجية:
الهيكل:
/opt/app/
├── app.jar
└── config/
└── application.yml
التشغيل:
java -jar /opt/app/app.jar
سيجد Spring Boot تلقائيًا /opt/app/config/application.yml
تحديد ملف
java -jar app.jar --spring.config.location=file:/path/to/config/
الخصائص الحساسة
تأمين كلمات المرور
ممارسة سيئة:
spring:
datasource:
password: supersecret123 # ❌ كلمة مرور واضحة
ممارسات جيدة:
1. متغيرات البيئة:
spring:
datasource:
password: ${DATABASE_PASSWORD} # ✅ متغير البيئة
2. Spring Cloud Config Server:
- مركزية التكوين
- تشفير الخصائص الحساسة
3. HashiCorp Vault:
- إدارة احترافية للأسرار
4. ملفات .env (للتطوير فقط):
DATABASE_PASSWORD=secret
مهم: لا تقم أبدًا بارتكاب كلمات المرور في Git!
تمارين عملية
التمرين 1: التكوين الأساسي
الهدف: تكوين المنفذ واسم التطبيق
التعليمات:
- قم بإنشاء مشروع Spring Boot
- في
application.properties، قم بتكوين:- المنفذ: 8081
- الاسم: "My Greeting App"
- ابدأ التطبيق
- تحقق من أن الخادم يبدأ على المنفذ 8081
التمرين 2: تحويل properties → yml
الهدف: تحويل ملف properties إلى yml
ملف properties المعطى:
server.port=8080
spring.application.name=user-service
spring.datasource.url=jdbc:postgresql://localhost:5432/users
spring.datasource.username=admin
spring.jpa.show-sql=true
المطلوب: تحويل إلى تنسيق YAML
التمرين 3: خصائص مخصصة
الهدف: إنشاء واستخدام خصائص مخصصة
التعليمات:
- أضف في
application.yml:app:
welcome-message: Bienvenue!
max-users: 100 - قم بإنشاء وحدة تحكم تعرض هذه القيم
- اختبر
التمرين 4: ملفات التعريف
الهدف: إنشاء ملفات شخصية dev و prod
التعليمات:
- قم بإنشاء
application-dev.yml:- المنفذ: 8080
- السجلات: DEBUG
- قم بإنشاء
application-prod.yml:- المنفذ: 80
- السجلات: WARN
- اختبر تفعيل كل ملف شخصي
أسئلة المراجعة
-
ما الفرق بين application.properties و application.yml؟
-
كيف تقوم بتفعيل ملف شخصي في Spring Boot؟
-
ما هو ترتيب الأولوية لملفات التكوين؟
-
كيف تقوم بحقن خاصية مخصصة في فئة؟
-
ما هي التعليمة التي تستخدمها لفئة تكوين تحتوي على عدة خصائص؟
-
كيف تستخدم متغير بيئة في application.yml؟
-
ما هي القيم الممكنة لـ
spring.jpa.hibernate.ddl-auto؟ -
لماذا لا يجب أبدًا ارتكاب كلمات المرور في application.properties؟
ملخص الفصل
النقاط الرئيسية
- يدعم Spring Boot
.propertiesو.yml .ymlأكثر قابلية للقراءة للهياكل المعقدة- تسمح ملفات التعريف بتكوينات حسب البيئة
@Valueلخاصية واحدة،@ConfigurationPropertiesلعدة خصائص- استخدام متغيرات البيئة للبيانات الحساسة
- لا تقم أبدًا بارتكاب كلمات المرور
الممارسات الجيدة
- استخدام ملفات التعريف لكل بيئة
- توسيع التكوينات الحساسة
- توثيق الخصائص المخصصة
- توفير قيم افتراضية
- استخدام أسماء خصائص وصفية
- فصل التكوين المشترك عن التكوين الخاص
الخطوات التالية
في الفصل التالي، سندرس:
- @SpringBootApplication
- @RestController مقابل @Controller
- @GetMapping, @PostMapping، إلخ.
- @Autowired وحقن التبعية
- @Component, @Service, @Repository