Creatring Beans with @Bean and @Configuration
توضیحات جلسه
جزوه و مستندات
مفاهیم کلیدی
@Configuration
یک annotation در سطح کلاس است که به Spring اعلام میکند این کلاس حاوی تعاریف و متدهای سازنده bean است و باید پردازش و پیکربندی شود.
@Bean
یک annotation در سطح متد است که داخل کلاسهای @Configuration قرار میگیرد و به کانتینر Spring دستور میدهد خروجی متد را به عنوان یک Spring Bean مدیریت کند.
- Java-Based Configuration
رویکرد پیکربندی صریح در Spring با استفاده از کدهای جاوا و انوتیشنهای @Configuration و @Bean بهجای استفاده از فایلهای قدیمی XML.
- Third-Party Libraries Integration
فرآیند ثبت کلاسهای کتابخانههای خارجی به عنوان bean در کانتینر، در شرایطی که دسترسی مستقیم به سورسکد کلاس برای قرار دادن انوتیشن @Component وجود ندارد.
- Bean Name Aliasing / Renaming
قابلیت تغییر نام یا تخصیص چندین نام مستعار به یک bean از طریق مشخصههای name یا value در انوتیشن @Bean.
موارد مصاحبه ای
- محدودیتهای اصلی استفاده از
@Componentچیست و چه زمانی باید از@Beanاستفاده کرد؟
انوتیشن @Component روی کلاسهایی که سورس آنها را نداریم (مانند کتابخانههای شخص ثالث) قابل استفاده نیست و همچنین برای ساخت آبجکتهایی که نیاز به لاجیک شرطی یا تنظیمات پیچیده قبل از ساخت دارند محدودیت دارد؛ در این شرایط از متدهای @Bean استفاده میشود.
- تفاوت اصلی
@Componentو@Beanچیست؟
انوتیشن @Component در سطح کلاس قرار میگیرد و با فرآیند خودکار Component Scanning مدیریت میشود، در حالی که @Bean در سطح متد و داخل کلاسهای پیکربندی قرار میگیرد و ساخت نمونه را به صورت دستی و صریح کنترل میکند.
- نام پیشفرض یک
beanساخته شده با متد@Beanچیست و چگونه میتوان آن را تغییر داد؟
نام پیشفرض برابر با نام همان متد است، اما میتوان با استفاده از مشخصه name یا value در انوتیشن مانند @Bean("customName") یا @Bean(name = {"name1", "name2"}) آن را تغییر داد یا چند نام برای آن تعریف کرد.
- اگر یک متد
@Beanبه عنوان ورودی پارامتر دریافت کند،Springچگونه آن پارامتر را مقداردهی میکند؟
کانتینر Spring به صورت خودکار پارامترهای ورودی متد @Bean را به عنوان وابستگی در نظر گرفته و beanهای متناظر را از کانتینر پیدا کرده و تزریق میکند.
سناریو کاربردی
- تعریف
beanسفارشی برای یک کتابخانه شخص ثالث و تغییر نام آن
در سناریویی که از یک ماژول خارجی مانند ObjectMapper یا یک کلاینت خارجی استفاده میشود، به دلیل عدم دسترسی به سورس آن کلاس، از ساختار زیر برای ثبت دستی در کانتینر استفاده میشود:
@Configuration
public class AppConfig {
@Bean(name = {"jsonMapper", "customObjectMapper"})
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
// اعمال تنظیمات و پیکربندی اختصاصی
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper;
}
@Bean
public PaymentService paymentService(ObjectMapper objectMapper) {
// تزریق خودکار وابستگی تعریفشده در متد بالا
return new PaymentService(objectMapper);
}
}
در این سناریو، آبجکت ObjectMapper با تنظیمات اختصاصی ساخته شده و با نامهای jsonMapper و customObjectMapper در کانتینر رجیستر میشود و مستقیماً به سازنده PaymentService تزریق میگردد.
