پرش به محتوای اصلی
مسیر تخصصی جاوا و Spring
درخواست پروژهتدریس خصوصیارتباط با ماراهنما
جاواپرو v1.2.36یاد بگیر، تمرین کن، حرفه‌ای بساز
خانهدوره‌هاآموزش رایگانوبلاگمدرس‌هاخدمات
خانه10 راز اسپرینگ‌بوت(Spring Boot) برای کدنویسی کارآمد | جاواپرو
مقالات جاوا

10 راز اسپرینگ‌بوت(Spring Boot) برای کدنویسی کارآمد

اسپرینگ‌بوت به‌خاطر افزایش بهره‌وری توسعه‌دهندگان مشهور است — پیش‌فرض‌های از‌پیش‌تعریف‌شده، سرورهای درون‌ساخته (Embedded) و پیکربندی خودکار…

۱۸ شهریور ۱۴۰۴۸ دقیقه مطالعهمقالات جاوارحمن زارعی
10 راز اسپرینگ‌بوت(Spring Boot) برای کدنویسی کارآمد
محتوای منتخب جاواپرو

خلاصه مطلب

اسپرینگ‌بوت به‌خاطر افزایش بهره‌وری توسعه‌دهندگان مشهور است — پیش‌فرض‌های از‌پیش‌تعریف‌شده، سرورهای درون‌ساخته (Embedded) و پیکربندی خودکار…
نوع محتوامقاله آموزشی
موضوعمقالات جاوا
زمان مطالعه۸ دقیقه مطالعه
آخرین ویرایش۲۳ شهریور ۱۴۰۴

10 راز اسپرینگ بوت برای کدنویسی کارآمد

10 راز اسپرینگ‌بوت برای کدنویسی کارآمد

اسپرینگ‌بوت به‌خاطر افزایش بهره‌وری توسعه‌دهندگان مشهور است — پیش‌فرض‌های از‌پیش‌تعریف‌شده، سرورهای درون‌ساخته (Embedded) و پیکربندی خودکار (Auto-Configuration).

اما اگر مدتی با آن کار کرده باشید، احتمالاً متوجه شده‌اید که بعضی وقت‌ها کدتان شلوغ و تکراری به‌نظر می‌رسد یا زمانتان صرف حل مسائلی می‌شود که اسپرینگ‌بوت خودش راه‌حل آماده برایشان دارد — فقط کافی است ترفند درست را بلد باشید.

بعد از چندین سال کار با اسپرینگ‌بوت در سیستم‌های واقعی، مجموعه‌ای از نکات کمتر شناخته‌شده اما بسیار کاربردی جمع‌آوری کرده‌ام که باعث می‌شوند اپلیکیشن‌های شما ساده‌تر، تمیزتر و به‌مراتب کارآمدتر شوند.

بریم سراغ اصل مطلب.

۱. شرط‌های سفارشی با @Conditional

بیشتر توسعه‌دهندگان فقط از @ConditionalOnProperty استفاده می‌کنند، اما سیستم شرطی اسپرینگ‌بوت خیلی قدرتمندتر از این‌هاست.

شما می‌توانید شرط‌های سفارشی خودتان را تعریف کنید تا ایجاد Beanها را به صورت پویا (Dynamic) کنترل کنید.

برای مثال، می‌توانید یک Bean را فقط زمانی بارگذاری کنید که Redis در دسترس باشد:

Java Codejava
public class OnRedisAvailableCondition implements Condition {
@Override
public boolean matches(ConditionContext context, 
AnnotatedTypeMetadata metadata) {
try (Socket socket = new Socket("localhost", 6379)) {
return true;
} catch (Exception e) {
return false;
}
}
}

@Configuration
public class RedisConfig {
@Bean
@Conditional(OnRedisAvailableCondition.class)
public RedisClient redisClient() {
return new RedisClient("localhost", 6379);
}
}

اپلیکیشن شما بسته به شرایط محیط (Environment) به‌صورت هوشمندانه خودش را تطبیق می‌دهد، بدون اینکه در زمان اجرا (Startup) دچار خطا شود.

۲. کاهش زمان راه‌اندازی با Lazy Initialization

اپلیکیشن‌های اسپرینگ‌بوت معمولاً سنگین هستند، مخصوصاً در معماری میکروسرویس‌ها.

از نسخه ۲.۲ Spring Boot به بعد می‌توانید ایجاد Beanها را به‌تعویق بیندازید تا فقط زمانی ساخته شوند که واقعاً به آن‌ها نیاز دارید.

کافی است تنها یک پراپرتی را تغییر دهید:

spring.main.lazy-initialization=true

برای مثال، یک کنترلر مدیریتی (Admin Controller) که به‌ندرت استفاده می‌شود، حتی در زمان راه‌اندازی اپلیکیشن بارگذاری نمی‌شود و فقط وقتی اولین بار فراخوانی شود ساخته خواهد شد.

این ویژگی مثل یک سلاح مخفی برای کاهش زمان استارتاپ در اپلیکیشن‌های بزرگ عمل می‌کند.

۳. تغییرات اولیه در Context با ApplicationContextInitializer

آیا لازم دارید قبل از اینکه Beanها بارگذاری شوند، کانتکست اسپرینگ را دستکاری کنید؟

اینجاست که ApplicationContextInitializer به کار می‌آید.

Java Codejava
public class TenantContextInitializer 
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext context) {
String tenant = System.getenv("TENANT");
context.getEnvironment().setActiveProfiles(tenant != null ? 
tenant : "default");
}

کافی است آن را در فایل spring.fact or ies ثبت کنید:

or g.springframew or k.context.ApplicationContextInitializer=\
com.example.TenantContextInitializer

این روش برای چندمستاجری (Multi-Tenant) یا راه‌اندازی پویا با پروفایل‌های مختلف فوق‌العاده کاربردی است.

۴. قدرت پنهان @ConfigurationProperties با Mapها و Listها

بیشتر توسعه‌دهندگان فقط خصوصیات ساده (Flat Properties) را نگاشت می‌کنند.

اما شما می‌توانید تنظیمات ساختاریافته را مستقیماً به آبجکت‌ها متصل (Bind) کنید.

مثال تنظیمات در فایل application.yml:

app:
  servers:
    - url: https://api1.example.com
      timeout: 5000
    - url: https://api2.example.com
      timeout: 3000
  features:
    auth: true
    cache: false

کلاس جاوا برای نگاشت مستقیم این تنظیمات:

Java Codejava
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private List<ServerConfig> servers;
private Map<String, Boolean> features;

  // getters/setters
public static class ServerConfig {
private String url;
private int timeout;
}
}


این روش باعث می‌شود تنظیمات شما تمیزتر باشند، مقادیر کمتری به‌صورت هاردکد داخل کد نوشته شوند و در نتیجه انعطاف‌پذیری بیشتری داشته باشید.

. ساخت Starterهای داخلی با Auto-Configuration

اگر در یک تیم یا سازمان بزرگ کار کرده باشید، احتمالاً متوجه تکرار کدهای مشابه در سرویس‌های مختلف شده‌اید؛ مثل:

پیکربندی لاگینگ

مانیتورینگ

تنظیمات امنیتی

تنظیمات کش

و این لیست همین‌طور ادامه دارد.

خب، عالی نمی‌شد اگر توسعه‌دهندگان فقط یک وابستگی (Dependency) اضافه می‌کردند و به شکل خودکار تمام Beanهای موردنیاز از قبل پیکربندی‌شده در اختیارشان قرار می‌گرفت؟

دقیقاً همین کاری است که Spring Boot Starterها انجام می‌دهند.

و نکته مهم اینجاست: شما می‌توانید Starterهای مخصوص خودتان را بسازید.

گام اول: ساخت یک کلاس Auto-Configuration

این کلاس چیزی نیست جز یک کلاس معمولی با Annotation @Configuration که Beanها را تعریف می‌کند.

Java Codejava
@Configuration
public class LoggingAutoConfiguration {
@Bean
public LoggerService loggerService() {
return new LoggerService();
}
}

اگر این کلاس داخل یک JAR قرار داشته باشد، می‌خواهیم اسپرینگ‌بوت به‌صورت خودکار و به محض اضافه‌شدن این JAR به وابستگی‌ها، آن را بارگذاری کند.

گام دوم: معرفی آن به اسپرینگ‌بوت

اگر از Spring Boot 2.x استفاده می‌کنید:

یک فایل در مسیر زیر بسازید:

src/main/resources/META-INF/spring.fact or ies

و این خط را اضافه کنید:

or g.springframew or k.boot.autoconfigure.EnableAutoConfiguration=\
com.example.LoggingAutoConfiguration

این خط به اسپرینگ‌بوت می‌گوید:

«هی اسپرینگ‌بوت! وقتی اپلیکیشن من شروع شد، کلاس LoggingAutoConfiguration رو هم به‌صورت خودکار پیکربندی کن.»

اما اگر از Spring Boot 3.x (روش جدیدتر) استفاده می‌کنید:

اسپرینگ‌بوت ۳ یک مکانیزم تمیزتر معرفی کرده است. به‌جای استفاده از spring.fact or ies، باید یک فایل در مسیر زیر بسازید:

src/main/resources/META-INF/spring/ or g.springframew or k.boot.autoconfigure.AutoConfiguration.imp or ts

و کافی است کلاس خود را به سادگی در فایل فهرست کنید:

com.example.LoggingAutoConfiguration

گام سوم: استفاده از آن

حالا این پروژه را به یک JAR بسته‌بندی کنید (مثلاً logging-starter.jar) و در یک پروژه دیگر اسپرینگ‌بوت اضافه کنید.

بدون نوشتن حتی یک خط پیکربندی، آن پروژه به‌صورت خودکار یک LoggerService Bean آماده برای تزریق (Inject) خواهد داشت.

Java Codejava
@RestController
public class HelloController {
private final LoggerService logger;
public HelloController(LoggerService logger) {
this.logger = logger;
}

@GetMapping("/hello")
public String hello() {
logger.log("Hello endpoint called");
return "Hello W or ld!";
}
}

هیچ پیکربندی اضافه‌ای لازم نیست.

هیچ تکراری در تنظیمات وجود ندارد.

فقط کافی است وابستگی (Dependency) را اضافه کنید و همه‌چیز به‌صورت خودکار کار می‌کند.

چرا این کار قدرتمند است؟

استانداردسازی لاگینگ، مانیتورینگ یا امنیت در تمام سرویس‌های شرکت

کاهش کدهای تکراری (Boilerplate) برای هر میکروسرویس جدید

کپسوله‌سازی بهترین روش‌ها (Best Practices) تا توسعه‌دهندگان مجبور نباشند دوباره چرخ را اختراع کنند

این دقیقاً همان روشی است که خود اسپرینگ‌بوت ساخته شده است — Starterهای درون‌ساخته مثل spring-boot-starter-data-jpa یا spring-boot-starter-web دقیقاً از همین مکانیزم استفاده می‌کنند.

۶. تست قدرتمند با Testcontainers

وقتی در محیط واقعی از PostgreSQL، Kafka یا Redis استفاده می‌کنید، دیگر قانع نشوید به استفاده از Mockهای ساده مثل H2.

با Testcontainers می‌توانید سرویس‌های واقعی را داخل Docker و به صورت درلحظه (On-demand) بالا بیاورید.

Java Codejava
@SpringBootTest
@Testcontainers
public class UserReposit or yTest {
@Container
static PostgreSQLContainer<?> postgres = 
new PostgreSQLContainer<>("postgres:15");

@DynamicPropertySource
static void registerProps(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.passw or d", postgres::getPassw or d);
}

@Autowired
private UserReposit or y reposit or y;

@Test
void shouldSaveUser() {
reposit or y.save(new User("Alice"));
assertThat(reposit or y.findAll()).hasSize(1);
}
}

تست‌های شما روی زیرساخت واقعی اجرا می‌شوند، نه فقط روی Mockها.

۷. کدنویسی رویدادمحور با @EventListener

به‌جای اینکه سرویس‌ها را با فراخوانی مستقیم به هم زنجیر کنید، از رویدادهای اسپرینگ برای جداسازی اجزای سیستم استفاده کنید.

Java Codejava
// Publisher
@Component
public class  or derService {

@Autowired
private ApplicationEventPublisher publisher;

public void place or der( or der  or der) {
// ذخیره سفارش
publisher.publishEvent(new  or derPlacedEvent( or der));
}
}

// Listener
@Component
public class NotificationHandler {
@EventListener
public void handle or derPlaced( or derPlacedEvent event) {
System.out.println("ارسال ایمیل برای سفارش: " +
event.get or der().getId());
}
}

این رویکرد باعث کاهش وابستگی‌ها می‌شود و کد شما را ماژولارتر و تست‌پذیرتر می‌کند.

۸. اندپوینت‌های مخفی Actuat or برای Debug

بیشتر افراد فقط از /actuat or /health استفاده می‌کنند.

اما Actuat or چند اندپوینت قدرتمند برای اشکال‌زدایی دارد:

/actuat or /conditions → ببینید چرا یک Bean ساخته شد یا نشد.

/actuat or /configprops → تمام تنظیمات Bind‌شده را یکجا بررسی کنید.

/actuat or /mappings → همه‌ی اندپوینت‌های REST را لیست کنید.

نمونه پیکربندی:

management:
endpoints:
web:
exposure:

include: health,info,conditions,configprops,mappings

این ویژگی یک نجات‌دهنده زمان واقعی در هنگام دیباگ مشکلات بارگذاری Beanهاست.

کنترل دقیق‌تر با ApplicationRunner Events

گاهی لازم است در زمان استارتاپ منطق سفارشی اجرا کنید.

خیلی از توسعه‌دهندگان سراغ @PostConstruct می‌روند، اما همیشه ابزار مناسبی نیست:

@PostConstruct قبل از آماده‌شدن کامل کانتکست اجرا می‌شود، بنابراین ممکن است NullPointerException بگیرید اگر بعضی Beanها هنوز مقداردهی نشده باشند.

کنترل دقیقی روی زمان اجرای منطق شما نسبت به چرخه حیات اپلیکیشن نمی‌دهد.

راه‌حل: استفاده از ApplicationRunner

ApplicationRunner بعد از استارتاپ کانتکست و زمانی که تمام Beanها آماده هستند اجرا می‌شود.

Java Codejava
@Component
public class WarmupRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
System.out.println("Warming up caches...");
// Call DB, load configs,  or  prime caches here
}
}

حتی می‌توانید هنگام اجرای برنامه آرگومان‌ها را پاس بدهید:

java -jar app.jar--seed-data=true

@Override
public void run(ApplicationArguments args) {
if (args.containsOption("seed-data")) {
System.out.println("Seeding initial data...");
}
}

این دقیقاً مناسب وظایف اولیه‌ای است که به Beanهای کاملاً مقداردهی‌شده وابسته‌اند.

۱۰. گروه‌بندی پروفایل‌ها برای پیکربندی تمیزتر

معمولاً پروفایل‌ها را یکی‌یکی فعال می‌کنید با:

- - spring.profiles.active=dev

و در application.yml ممکن است داشته باشید:

spring:
profiles: dev
spring:
profiles: h2

spring:
profiles: debug

اگر بخواهید مد توسعه (dev) با دیتابیس درون‌حافظه‌ای H2 و لاگ‌های دیباگ داشته باشید، باید به این شکل اجرا کنید:

- - spring.profiles.active=dev,h2,debug

این کار هم تکراری است و هم مستعد خطاست.

اینجاست که Profile Groups نجات‌بخش هستند

از نسخه ۲.۴ به بعد، اسپرینگ‌بوت گروه‌های پروفایل را معرفی کرده که در آن یک پروفایل می‌تواند به‌طور خودکار پروفایل‌های دیگر را هم فعال کند.

spring:
profiles:
group:
dev: [h2,debug]
prod: [mysql,logging]

این یعنی:

وقتی dev را فعال می‌کنید، اسپرینگ‌بوت در پشت صحنه h2 و debug را هم فعال می‌کند.

وقتی prod را فعال می‌کنید، mysql و logging هم فعال می‌شوند.

پس فقط کافی است اجرا کنید:

- - spring.profiles.active=dev

و اپلیکیشن شما درست مثل این عمل خواهد کرد:

- - spring.profiles.active=dev,h2,debug

چرا این مفید است؟

بدون تکرار: لازم نیست هر بار به خاطر بسپارید dev = dev + h2 + debug.

سازگاری: همه اعضای تیم هنگام اجرای dev دقیقاً همان مجموعه پروفایل را می‌گیرند.

انعطاف‌پذیری: می‌توانید محیط‌های پیچیده بسازید بدون اینکه فایل application.yml شلوغ شود.

مثال:

فرض کنید روی یک میکروسرویس کار می‌کنید:

در dev می‌خواهید محیط سبک داشته باشید → دیتابیس H2 و لاگ‌های دیباگ اضافه.

در prod می‌خواهید محیط کامل داشته باشید → MySQL و لاگ‌های سطح تولید.

با استفاده از profile groups:

spring:
profiles:
group:
dev: [h2,debug]
prod: [mysql,logging]

حالا:

وقتی محلی با

- - spring.profiles.active=dev

اجرا می‌کنید، به‌طور خودکار به H2 وصل می‌شود و لاگ‌های دیباگ فعال می‌شوند.

وقتی با

- - spring.profiles.active=prod

اجرا می‌کنید، به‌طور خودکار به MySQL وصل می‌شود و لاگ‌های تولیدی فعال می‌شوند.

توسعه‌دهندگان دیگر لازم نیست چندین پروفایل را به یاد داشته باشند — یک کلمه کلیدی کافی است.

جمع‌بندی

بیشتر توسعه‌دهندگان فقط به ویژگی‌های سطحی اسپرینگ‌بوت بسنده می‌کنند.

اما افزایش واقعی بهره‌وری زمانی رخ می‌دهد که به سراغ قابلیت‌های پنهان آن بروید:

  • شرط‌های سفارشی برای Beanهای تطبیقی
  • Lazy initialization برای استارتاپ سریع‌تر
  • معماری رویدادمحور با @EventListener
  • Starterهای داخلی برای استانداردسازی تنظیمات رایج
  • تست زیرساخت واقعی با Testcontainers
  • اندپوینت‌های مخفی Actuat or برای دیباگ حرفه‌ای

این رازها فقط چند خط کد را نجات نمی‌دهند — اپلیکیشن‌های شما را هوشمندتر، سریع‌تر و قابل‌نگهداری‌تر می‌کنند.

منبع: نوشته شده توسط Ujjawal Rohra


کاربران جاواپرو که علاقه‌مند به یادگیری Spring Boot هستند، در دوره‌های زیر ثبت‌نام کرده‌اند:

  • دوره طلایی Spring Core
  • دوره آموزش فریمورک Spring Boot
  • پروژه‌محور Spring Boot - سیستم دانشگاه
  • دوره دژبان Spring security
  • دوره جامع نخبگان معماری میکروسرویس با Java و Spring Boot
نام گالری فیلم و نام ویدیو
برچسب‌هامقالات جاوا
دسترسی سریع

فهرست مطلب

۱10 راز اسپرینگ‌بوت برای کدنویسی کارآمد
ادامه مسیر

پیشنهاد جاواپرو

موضوع را با آموزش‌های مرتبط ادامه دهید و نکته‌های کاربردی را در مسیر خود نگه دارید

مشاهده دوره‌ها
مطالب پیشنهادی

ادامه مطالعه

xدسته‌بندی نشده
۱۱ دی ۱۳۹۸ مطالعه کوتاه

x

پادکست شماره 3 – راه های کسب درآمد از برنامه نویسی

مطالعه مطلب
پادکست شماره 3 - راه های کسب درآمد از برنامه نویسیپادکست
۲۹ اردیبهشت ۱۴۰۴ پادکست آموزشی

پادکست شماره 3 - راه های کسب درآمد از برنامه نویسی

در این پادکست برنامه نویسی به شیوه ها و راه های کسب درآمد از برنامه نویسی پرداخته ایم. یک کاغذ و قلم بردارید و به پادکست گوش بدید.

شنیدن پادکست
پادکست شماره 2 - چگونه وارد فضای برنامه نویسی شویم؟پادکست
۲۹ اردیبهشت ۱۴۰۴ پادکست آموزشی

پادکست شماره 2 - چگونه وارد فضای برنامه نویسی شویم؟

در این پادکست برنامه نویسی یاد میگیریم که چگونه وارد فضای برنامه نویسی شویم و تخصص برنامه نویسی را به دست آوریم.

شنیدن پادکست
جاواپرومرجع تخصصی یادگیری و توسعهٔ جاوا

تجربه‌ای منظم، ساده و حرفه‌ای برای یادگیری عمیق جاوا، Spring و مهندسی نرم‌افزار؛ قابل استفاده در موبایل، تبلت و دسکتاپ

یادگیری

همه دوره‌هاآموزش رایگانمسیر یادگیریمدرس‌ها

جاواپرو

درباره ماخدمات تخصصیدرخواست پروژهتدریس خصوصیبلاگ فنیرپورتاژ آگهی

پشتیبانی

تماس با ماپرسش‌های متداولقوانین و حریم خصوصیبروزرسانی‌های جاواپروثبت تیکت

مجوزها

نماد اعتمادنماد اعتماد
خرید امنپرداخت فقط در درگاه رسمیپشتیبانی آموزشیمسیر ارتباط شفاف و پیگیری‌پذیردسترسی پایداروب‌اپ واکنش‌گرا روی همه دستگاه‌ها
© ۱۴۰۵ جاواپرو؛ همه حقوق محفوظ استتوسعه توسط پایاپینگ
خانهدوره‌هاسبد