جلسه شماره 138رایگان

CommandLineRunner & ApplicationRunner in Spring

00:32:30

توضیحات جلسه

🎥 این ویدیو قسمت صد و بیستم از بوت‌کمپ رایگان جاوا و نوزدهمین جلسه از پلی‌لیست تخصصی آموزش فریم‌ورک اسپرینگ است. 📚 در این جلسه به سراغ بررسی مفهوم و کاربرد CommandLineRunner و ApplicationRunner در اسپرینگ بوت می‌رویم تا ببینیم چطور می‌توانیم کدهای خود را همزمان با بالا آمدن برنامه به صورت خودکار اجرا و تست کنیم. در این ویدیو ابتدا به صورت تئوری با این اینترفیس‌ها آشنا می‌شویم و سپس در بخش عملی، کدهای نوشته‌شده در جلسات قبل را تست می‌کنیم. همچنین نحوه کار با فایل data.sql، پیش‌بارگذاری داده‌ها (Preload Data) در عمل و تست سایر متدهای CRUD را قدم‌به‌قدم پیاده‌سازی و بررسی می‌کنیم. در این جلسه یاد می‌گیریم: ⚙️ تفاوت و کاربرد تئوری CommandLineRunner و ApplicationRunner در اسپرینگ بوت 🛠️ پیاده‌سازی عملی این اینترفیس‌ها برای اجرای کد در زمان راه‌اندازی برنامه 🗂️ نحوه استفاده از فایل data.sql برای مدیریت اسکریپت‌های دیتابیس 🚀 پیش‌بارگذاری داده‌ها (Preload Data) در عمل 🧪 تست و بررسی سایر متدهای CRUD در پروژه 🧠 جمع‌بندی نکات کلیدی و مرور نحوه راه‌اندازی اولیه داده‌ها در پروژه اگر در حال یادگیری اسپرینگ بوت هستید، تسلط بر نحوه اجرای خودکار کارها هنگام راه‌اندازی برنامه یکی از ابزارهای ضروری برای تست و آماده‌سازی داده‌های اولیه است. 📌 یوتیوب: https://youtube.com/@farzadafi 📌 آپارت: https://aparat.com/farzadafi 📌 وب سایت: https://farzadafi.ir 📌 گروه پرسش و پاسخ تلگرام: @programmingByFarzadAfi 💬 گروه پرسش و پاسخ بله: @programming_by_farzadafi وب سایت: https://farzadafi.ir هر سوالی داشته باشید می‌توانید در گروه بپرسید تا من یا مربی‌های گروه کمکتان کنیم 💬 🎯 بوت‌کمپ رایگان جاوا – آموزش کاملاً پروژه‌محور برای یادگیری عمیق جاوا و ورود به بازار کار.

جزوه و مستندات

مفاهیم کلیدی

  • CommandLineRunner

اینترفیس تابعی (Functional Interface) در اسپرینگ بوت که متد run(String... args) را تعریف می‌کند؛ بین‌هایی که این اینترفیس را پیاده‌سازی کنند، بلافاصله پس از بارگذاری کامل کانتکست و سیم‌کشی تمام بین‌ها اجرا می‌شوند و آرگومان‌های خط فرمان را به صورت آرایه خام دریافت می‌کنند.

  • ApplicationRunner

اینترفیس تابعی مشابه CommandLineRunner در اسپرینگ بوت با متد run(ApplicationArguments args)؛ این اینترفیس آرگومان‌های خط فرمان را به صورت شیء پارس‌شده و ساختاریافته در اختیار توسعه‌دهنده قرار می‌دهد.

  • Startup Data Seeding

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

  • ApplicationArguments

کلاس ارائه‌شده توسط اسپرینگ بوت برای مدیریت آرگومان‌های خط فرمان با متدهای کاربردی نظیر getOptionValues()، که امکان دسترسی مستقیم به گزینه‌ها و مقادیر سوئیچ‌های ترمینال (مانند مقادیر دارای پیشوند --) را بدون نیاز به پیمایش دستی آرایه فراهم می‌سازد.

  • Database-Agnostic Preloading

مزیت بارگذاری اولیه داده‌ها از طریق لایه ریپازیتوری (Repository-based Preloading) که باعث می‌شود منطق مقداردهی اولیه نه تنها روی پایگاه‌های داده رابطه‌ای، بلکه روی دیتابیس‌های غیررابطه‌ای (NoSQL) نیز بدون وابستگی به سینتکس SQL اجرا شود.

موارد مصاحبه ای

  • تفاوت دقیق بین CommandLineRunner و ApplicationRunner چیست؟

هر دو در یک زمان از چرخه حیات برنامه اجرا می‌شوند، اما ورودی متد run در CommandLineRunner یک آرایه خام از نوع String... است؛ در حالی که ApplicationRunner ورودی را به صورت نمونه‌ای از ApplicationArguments دریافت می‌کند که متدهای تفکیک‌شده برای آرگومان‌های گزینه‌ای (Option Arguments) و بدون گزینه (Non-option Arguments) ارائه می‌دهد.

  • چرا استفاده از Runnerها نسبت به اسکریپت data.sql در مقداردهی اولیه انعطاف‌پذیرتر است؟

اسکریپت data.sql وابسته به موتور پایگاه داده رابطه‌ای و سینتکس SQL است؛ در حالی که استفاده از Runnerها به شما اجازه می‌دهد از اشیاء دامنه و متدهای ریپازیتوری بهره ببرید، منطق شرطی یا اعتبارسنجی بنویسید و داده‌ها را به شکل یکپارچه در پایگاه‌های داده رابطه‌ای و غیررابطه‌ای ذخیره کنید.

  • متدهای run در اینترفیس‌های Startup Runner دقیقاً در چه مرحله‌ای از چرخه حیات اپلیکیشن اجرا می‌شوند؟

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

  • چگونه می‌توان بدون ساخت یک کلاس مجزا از CommandLineRunner یا ApplicationRunner استفاده کرد؟

از آنجا که هر دو اینترفیس تابعی هستند، می‌توان آن‌ها را درون یک کلاس پیکربندی (@Configuration) به صورت یک متد با انوتیشن @Bean تعریف کرد که یک عبارت لامبدا (Lambda Expression) برمی‌گرداند.

سناریو کاربردی

  • مقداردهی اولیه مواد تشکیل‌دهنده (Ingredients) با استفاده از Bean مبتنی بر لامبدا

در این سناریو، به جای اجرای کوئری‌های متنی INSERT در فایل data.sql، یک بین از نوع CommandLineRunner تعریف شده و ریپازیتوری مستقیماً به آن تزریق می‌شود تا موجودیت‌ها با استفاده از متد save() در پایگاه داده ذخیره شوند:

@Configuration
public class DataLoaderConfig {

    @Bean
    public CommandLineRunner dataLoader(IngredientRepository repo) {
        return args -> {
            repo.save(new Ingredient("FLTO", "Flour Tortilla", Type.WRAP));
            repo.save(new Ingredient("COTO", "Corn Tortilla", Type.WRAP));
            repo.save(new Ingredient("GRBF", "Ground Beef", Type.PROTEIN));
            repo.save(new Ingredient("CARN", "Carnitas", Type.PROTEIN));
            repo.save(new Ingredient("TMTO", "Diced Tomatoes", Type.VEGGIES));
            repo.save(new Ingredient("LETC", "Lettuce", Type.VEGGIES));
            repo.save(new Ingredient("CHED", "Cheddar", Type.CHEESE));
            repo.save(new Ingredient("JACK", "Monterrey Jack", Type.CHEESE));
            repo.save(new Ingredient("SLSA", "Salsa", Type.SAUCE));
            repo.save(new Ingredient("SRCR", "Sour Cream", Type.SAUCE));
        };
    }
}

مراحل کار: ۱. تزریق خودکار IngredientRepository به عنوان ورودی متد بین. ۲. اجرای بدنه لامبدا بلافاصله پس از تکمیل استارتاپ اسپرینگ. ۳. ذخیره امن داده‌های اولیه از طریق ریپازیتوری با حفظ یکپارچگی مدل‌های دامنه.

بیشتر بدانید

  • دریافت پارامترهای تکرارپذیر با getOptionValues

متد getOptionValues("optionName") در شیء ApplicationArguments یک List<String> برمی‌گرداند؛ این ویژگی برای مواقعی کاربرد دارد که یک گزینه در خط فرمان چندین بار تکرار شده باشد (مانند --profile=dev --profile=debug).

  • نادیده‌گرفتن آرگومان‌های ورودی در کدهای Seed

اگر در منطق لود اولیه نیازی به خواندن متغیرهای محیطی یا ورودی‌های ترمینال ندارید، نادیده گرفتن پارامتر ورودی لامبدا (args) کاملاً استاندارد است و تاثیری در روند اجرای متد save() ندارد.

  • اهمیت ترتیب اجرا با انوتیشن Order

در صورت تعریف چند بین از نوع CommandLineRunner یا ApplicationRunner، می‌توانید با استفاده از انوتیشن @Order اولویت و ترتیب دقیق اجرای هر کدام را در زمان بالا آمدن برنامه مشخص کنید.