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

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

اسپرینگ‌بوت به‌خاطر افزایش بهره‌وری توسعه‌دهندگان و پیکربندی‌های خودکارش مشهور است، اما در عمل بسیاری از کدها شلوغ و تکراری می‌شوند و زمان زیادی هدر می‌رود. راه‌حل ساده است: فقط باید ترفندهای پنهان آن را بلد باشید. بعد از چند سال تجربه در پروژه‌های واقعی، مجم…

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

خلاصه مطلب

اسپرینگ‌بوت به‌خاطر افزایش بهره‌وری توسعه‌دهندگان و پیکربندی‌های خودکارش مشهور است، اما در عمل بسیاری از کدها شلوغ و تکراری می‌شوند و زمان زیادی هدر می‌رود. راه‌حل ساده است: فقط باید ترفندهای پنهان آن را بلد باشید. بعد از چند سال تجربه در پروژه‌های واقعی، مجم…
نوع محتوامقاله آموزشی
موضوعوبلاگ »
زمان مطالعه۸ دقیقه
آخرین ویرایش۲۳ شهریور ۱۴۰۴
10 راز اسپرینگ بوت برای کدنویسی کارآمد
10 راز اسپرینگ بوت برای کدنویسی کارآمد

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

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

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

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

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

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

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

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

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 به کار می‌آید.

public class TenantContextInitializer implements ApplicationContextInitializer { @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

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

@ConfigurationProperties(prefix = "app") public class AppProperties { private List servers; private Map 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ها را تعریف می‌کند.

@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) خواهد داشت.

@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 @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ها آماده هستند اجرا می‌شود.

@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: h2spring: 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 وصل می‌شود و لاگ‌های تولیدی فعال می‌شوند.

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

جمع‌بندی

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

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

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

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

برچسب‌هاوبلاگ »مقالات جاوا »اسپرینگ بوتspring bootspringآموزش spring bootآموزش springکدنویسی کارآمدجاواjavaConditional در اسپرینگ بوتAuto ConfigurationApplicationRunnerدوره اسپرینگ
ادامه مسیر

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

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

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

ادامه مطالعه

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

x

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

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

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

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

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

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

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

مطالعه مطلب
جاواپرومرجع تخصصی یادگیری و توسعهٔ جاوا

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

یادگیری

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

جاواپرو

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

پشتیبانی

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