اسپرینگبوت بهخاطر افزایش بهرهوری توسعهدهندگان مشهور است — پیشفرضهای ازپیشتعریفشده، سرورهای درونساخته (Embedded) و پیکربندی خودکار (Auto-Configuration).
اما اگر مدتی با آن کار کرده باشید، احتمالاً متوجه شدهاید که بعضی وقتها کدتان شلوغ و تکراری بهنظر میرسد یا زمانتان صرف حل مسائلی میشود که اسپرینگبوت خودش راهحل آماده برایشان دارد — فقط کافی است ترفند درست را بلد باشید.
بعد از چندین سال کار با اسپرینگبوت در سیستمهای واقعی، مجموعهای از نکات کمتر شناختهشده اما بسیار کاربردی جمعآوری کردهام که باعث میشوند اپلیکیشنهای شما سادهتر، تمیزتر و بهمراتب کارآمدتر شوند.
بریم سراغ اصل مطلب.
۱. شرطهای سفارشی با @Conditional
بیشتر توسعهدهندگان فقط از @ConditionalOnProperty استفاده میکنند، اما سیستم شرطی اسپرینگبوت خیلی قدرتمندتر از اینهاست.
شما میتوانید شرطهای سفارشی خودتان را تعریف کنید تا ایجاد Beanها را به صورت پویا (Dynamic) کنترل کنید.
برای مثال، میتوانید یک Bean را فقط زمانی بارگذاری کنید که Redis در دسترس باشد:
public class OnRedisAvailableCondition implements Condition { @Configuration |
اپلیکیشن شما بسته به شرایط محیط (Environment) بهصورت هوشمندانه خودش را تطبیق میدهد، بدون اینکه در زمان اجرا (Startup) دچار خطا شود.
۲. کاهش زمان راهاندازی با Lazy Initialization
اپلیکیشنهای اسپرینگبوت معمولاً سنگین هستند، مخصوصاً در معماری میکروسرویسها.
از نسخه ۲.۲ Spring Boot به بعد میتوانید ایجاد Beanها را بهتعویق بیندازید تا فقط زمانی ساخته شوند که واقعاً به آنها نیاز دارید.
کافی است تنها یک پراپرتی را تغییر دهید:
spring.main.lazy-initialization=true |
برای مثال، یک کنترلر مدیریتی (Admin Controller) که بهندرت استفاده میشود، حتی در زمان راهاندازی اپلیکیشن بارگذاری نمیشود و فقط وقتی اولین بار فراخوانی شود ساخته خواهد شد.
این ویژگی مثل یک سلاح مخفی برای کاهش زمان استارتاپ در اپلیکیشنهای بزرگ عمل میکند.
۳. تغییرات اولیه در Context با ApplicationContextInitializer
آیا لازم دارید قبل از اینکه Beanها بارگذاری شوند، کانتکست اسپرینگ را دستکاری کنید؟
اینجاست که ApplicationContextInitializer به کار میآید.
public class TenantContextInitializer |
کافی است آن را در فایل spring.fact or ies ثبت کنید:
or g.springframew or k.context.ApplicationContextInitializer=\ |
این روش برای چندمستاجری (Multi-Tenant) یا راهاندازی پویا با پروفایلهای مختلف فوقالعاده کاربردی است.
۴. قدرت پنهان @ConfigurationProperties با Mapها و Listها
بیشتر توسعهدهندگان فقط خصوصیات ساده (Flat Properties) را نگاشت میکنند.
اما شما میتوانید تنظیمات ساختاریافته را مستقیماً به آبجکتها متصل (Bind) کنید.
مثال تنظیمات در فایل application.yml:
app:
|
کلاس جاوا برای نگاشت مستقیم این تنظیمات:
@ConfigurationProperties(prefix = "app") // getters/setters |
این روش باعث میشود تنظیمات شما تمیزتر باشند، مقادیر کمتری بهصورت هاردکد داخل کد نوشته شوند و در نتیجه انعطافپذیری بیشتری داشته باشید.
. ساخت Starterهای داخلی با Auto-Configuration
اگر در یک تیم یا سازمان بزرگ کار کرده باشید، احتمالاً متوجه تکرار کدهای مشابه در سرویسهای مختلف شدهاید؛ مثل:
پیکربندی لاگینگ
مانیتورینگ
تنظیمات امنیتی
تنظیمات کش
و این لیست همینطور ادامه دارد.
خب، عالی نمیشد اگر توسعهدهندگان فقط یک وابستگی (Dependency) اضافه میکردند و به شکل خودکار تمام Beanهای موردنیاز از قبل پیکربندیشده در اختیارشان قرار میگرفت؟
دقیقاً همین کاری است که Spring Boot Starterها انجام میدهند.
و نکته مهم اینجاست: شما میتوانید Starterهای مخصوص خودتان را بسازید.
گام اول: ساخت یک کلاس Auto-Configuration
این کلاس چیزی نیست جز یک کلاس معمولی با Annotation @Configuration که Beanها را تعریف میکند.
@Configuration |
اگر این کلاس داخل یک JAR قرار داشته باشد، میخواهیم اسپرینگبوت بهصورت خودکار و به محض اضافهشدن این JAR به وابستگیها، آن را بارگذاری کند.
گام دوم: معرفی آن به اسپرینگبوت
اگر از Spring Boot 2.x استفاده میکنید:
یک فایل در مسیر زیر بسازید:
src/main/resources/META-INF/spring.fact or ies |
و این خط را اضافه کنید:
or g.springframew or k.boot.autoconfigure.EnableAutoConfiguration=\ |
این خط به اسپرینگبوت میگوید:
«هی اسپرینگبوت! وقتی اپلیکیشن من شروع شد، کلاس 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) خواهد داشت.
@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) بالا بیاورید.
@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
بهجای اینکه سرویسها را با فراخوانی مستقیم به هم زنجیر کنید، از رویدادهای اسپرینگ برای جداسازی اجزای سیستم استفاده کنید.
// Publisher @Autowired public void place or der( or der or der) { // Listener |
این رویکرد باعث کاهش وابستگیها میشود و کد شما را ماژولارتر و تستپذیرتر میکند.
۸. اندپوینتهای مخفی Actuat or برای Debug
بیشتر افراد فقط از /actuat or /health استفاده میکنند.
اما Actuat or چند اندپوینت قدرتمند برای اشکالزدایی دارد:
/actuat or /conditions → ببینید چرا یک Bean ساخته شد یا نشد.
/actuat or /configprops → تمام تنظیمات Bindشده را یکجا بررسی کنید.
/actuat or /mappings → همهی اندپوینتهای REST را لیست کنید.
نمونه پیکربندی:
management: include: health,info,conditions,configprops,mappings |
این ویژگی یک نجاتدهنده زمان واقعی در هنگام دیباگ مشکلات بارگذاری Beanهاست.
کنترل دقیقتر با ApplicationRunner Events
گاهی لازم است در زمان استارتاپ منطق سفارشی اجرا کنید.
خیلی از توسعهدهندگان سراغ @PostConstruct میروند، اما همیشه ابزار مناسبی نیست:
@PostConstruct قبل از آمادهشدن کامل کانتکست اجرا میشود، بنابراین ممکن است NullPointerException بگیرید اگر بعضی Beanها هنوز مقداردهی نشده باشند.
کنترل دقیقی روی زمان اجرای منطق شما نسبت به چرخه حیات اپلیکیشن نمیدهد.
راهحل: استفاده از ApplicationRunner
ApplicationRunner بعد از استارتاپ کانتکست و زمانی که تمام Beanها آماده هستند اجرا میشود.
@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 |
این دقیقاً مناسب وظایف اولیهای است که به Beanهای کاملاً مقداردهیشده وابستهاند.
۱۰. گروهبندی پروفایلها برای پیکربندی تمیزتر
معمولاً پروفایلها را یکییکی فعال میکنید با:
- - spring.profiles.active=dev |
و در application.yml ممکن است داشته باشید:
spring: spring: |
اگر بخواهید مد توسعه (dev) با دیتابیس درونحافظهای H2 و لاگهای دیباگ داشته باشید، باید به این شکل اجرا کنید:
- - spring.profiles.active=dev,h2,debug |
این کار هم تکراری است و هم مستعد خطاست.
اینجاست که Profile Groups نجاتبخش هستند
از نسخه ۲.۴ به بعد، اسپرینگبوت گروههای پروفایل را معرفی کرده که در آن یک پروفایل میتواند بهطور خودکار پروفایلهای دیگر را هم فعال کند.
spring: |
این یعنی:
وقتی 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: |
حالا:
وقتی محلی با
- - spring.profiles.active=dev |
اجرا میکنید، بهطور خودکار به H2 وصل میشود و لاگهای دیباگ فعال میشوند.
وقتی با
- - spring.profiles.active=prod |
اجرا میکنید، بهطور خودکار به MySQL وصل میشود و لاگهای تولیدی فعال میشوند.
توسعهدهندگان دیگر لازم نیست چندین پروفایل را به یاد داشته باشند — یک کلمه کلیدی کافی است.
جمعبندی
بیشتر توسعهدهندگان فقط به ویژگیهای سطحی اسپرینگبوت بسنده میکنند.
اما افزایش واقعی بهرهوری زمانی رخ میدهد که به سراغ قابلیتهای پنهان آن بروید:
این رازها فقط چند خط کد را نجات نمیدهند — اپلیکیشنهای شما را هوشمندتر، سریعتر و قابلنگهداریتر میکنند.
منبع: نوشته شده توسط Ujjawal Rohra
کاربران جاواپرو که علاقهمند به یادگیری Spring Boot هستند، در دورههای زیر ثبتنام کردهاند:
بستن *نام و نام خانوادگی * پست الکترونیک * متن پیام |
دوره های آموزشی برنامه نویسی
انجام پروژه های برنامه نویسی
تدریس خصوصی برنامه نویسی
بیش از 7 سال از فعالیت جاواپرو میگذرد
جاواپرو دارای مجوز نشر دیجیتال از وزارت فرهنگ و ارشاد اسلامی است
جهت ارتباط مستقیم با جاواپرو در واتساپ و تلگرام :
09301904690