JavaRush /Kurslar /All lectures for UZ purposes /Java-kod bilan konteynerlar konfiguratsiyasi

Java-kod bilan konteynerlar konfiguratsiyasi

All lectures for UZ purposes
Daraja, Dars
Mavjud

Asosiy tushunchalar: @Bean va @Configuration

Springdagi Java-konfiguratsiyaning yangi vositalarida markaziy artefaktlar @Configuration annotatsiyasi bilan belgilangan sinflar va @Bean annotatsiyasi bilan belgilanadigan metodlardir.

@Bean annotatsiyasi metod yangi obyekt yaratilishi, konfigurlanishi va IoC-kontext tomonidan boshqarilishini ko'rsatadi. XML-konfiguratsiya <beans/>ni biladiganlar uchun, @Bean annotatsiyasi <bean/> elementining rolini o'ynaydi. Siz @Component annotatsiyalari bilan belgilangan har qanday metodlarni @Bean annotatsiyasi bilan belgilangan metodlar bilan ishlatishingiz mumkin. Lekin u asosan @Configuration annotatsiyasi bilan belgilangan binlar bilan ishlatiladi.

Sinfni @Configuration bilan annotatsiya qilish, uning asosiy maqsadi bin ta'riflari manbai bo'lishini ko'rsatadi. Bundan tashqari, @Configuration bilan belgilangan sinflar boshqa metodni @Bean orqali chaqirish orqali binlar orasidagi bog'liqlikni aniqlashga imkon beradi. @Configuration bilan belgilangan eng oddiy sinf quyidagicha ko'rinadi:

Java
@Configuration
public class AppConfig {
    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }
}
Kotlin
@Configuration
class AppConfig {
    @Bean
    fun myService(): MyService {
        return MyServiceImpl()
    }
}

Tepardagi AppConfig sinfi quyidagi XML sinfiga ekvivalent: <beans/> from Spring:

<beans>
    <bean id="myService" class="com.acme.services.MyServiceImpl"/>
</beans>
To'liq @Configuration vs "yengil" rejim @Bean?

@Bean metodlari @Configuration bilan belgilangan sinflarda e'lon qilinmaganida, ularni "yengil" rejimda ishlatiladigan metodlar deyishadi. @Component annotatsiyasi yoki hatto oddiy sinfda e'lon qilingan metodlar boshqacha maqsadga ega, lekin @Bean annotatsiyasi bilan belgilangan metod u yerda bonus hisoblanadi. Masalan, yordamchi komponentlar har bir sinf uchun asosiy komponentni qo'shimcha metod orqali boshqaruvchi ko'rinishni taqdim etishi mumkin. Bunday holatlarda @Bean annotatsiyasi bilan belgilangan metodlar umumiy fabrika metodlari sifatida xizmat qiladi.

To'liq @Configurationdan farqli o'laroq, "yengil" metodlar @Bean ichki komponentning holatiga murojaat qiladi va, kerak bo'lsa, argumentlar bilan ishlaydi. Shu sababli, @Bean annotatsiyasi bilan belgilangan bunday metod boshqa @Bean annotatsiyasi bilan belgilangan metodlarni chaqirmasligi kerak. Har bir bunday metod faqat konkret bin havolasi uchun fabrika metodidir, hech qanday maxsus semantikani bajarish vaqtida taklif qilmaydi. Bu yerda ijobiy tomoni shundaki, runtime'da CGLIB subclassingni qo'llash zaruriyati yo'q, shuning uchun sinfni dizayn qilishda hech qanday cheklovlar yo'q (demak, o'z ichiga oluvchi sinf final bo'lishi mumkin va hokazo).

Oddiy holatlarda @Bean annotatsiyasi bilan belgilangan metodlar @Configuration bilan belgilangan sinflarda e'lon qilinishi kerak, bu esa "to'liq" rejimdan doimiy foydalanish va konteyner hayotiy siklini boshqarishga o'zaro bog'liqliklarni yo'naltiradi. Bu @Bean annotatsiyasi bilan belgilangan bitta metodni oddiy Java chaqiruv orqali xatolik bilan chaqirishdan qochish, bu esa "yengil" rejimda ishlashda aniqlanishi qiyin bo'lgan xatolarni kamaytirishga yordam beradi.

@Bean va @Configuration annotatsiyalari quyidagi bo'limlarda batafsil ko'rib chiqiladi. Ammo avval biz Java asosida konfiguratsiya yordamida Spring konteynerini yaratishning turli usullarini ko'rib chiqamiz.

Spring konteynerini yaratish AnnotationConfigApplicationContext yordamida

Quyidagi bo'limlar Spring 3.0 da joriy qilingan AnnotationConfigApplicationContext haqida ma'lumot beradi. Bu ApplicationContext interfeysining universal amalga oshirilishi faqat @Configuration annotatsiyasi bilan belgilangan sinflarni emas, balki oddiy @Component annotatsiyasi bilan belgilangan sinflarni va JSR-330 metama'lumotlari bilan belgilangan sinflarni ham qabul qila oladi.

Agar kiruvchi ma'lumot sifatida @Configuration annotatsiyasi bilan belgilangan sinflar ko'rsatilgan bo'lsa, @Configuration annotatsiyasi bilan belgilangan sinf o'zi bin ta'rifi sifatida ro'yxatdan o'tkaziladi va sinfda e'lon qilingan barcha @Bean annotatsiyasi bilan belgilangan metodlar ham bin ta'riflari sifatida ro'yxatdan o'tkaziladi.

Agar kiruvchi ma'lumot sifatida @Component annotatsiyasi bilan belgilangan sinflar yoki JSR-330dan kelgan bo'lsa, ular bin ta'riflari sifatida ro'yxatdan o'tkaziladi va ulardagi kerakli joylarda @Autowired yoki @Inject kabi injektiv metama'lumotlar ishlatiladi.

Oddiy konstruktsiya

Tuproqdan ClassPathXmlApplicationContextni yaratishda kiruvchi ma'lumot sifatida XML fayllari ishlatilganidek, siz @Configuration annotatsiyasi bilan belgilangan sinflarni kiruvchi ma'lumot sifatida ishlatib, AnnotationConfigApplicationContextni yaratishingiz mumkin. Bu Spring konteynerini to'liq XMLsiz ishlatishga imkon beradi, quyidagi misolda ko'rsatilganidek:

Java
public static void main(String[] args) {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
    MyService myService = ctx.getBean(MyService.class);
    myService.doStuff();
}
Kotlin
import org.springframework.beans.factory.getBean
fun main() {
    val ctx = AnnotationConfigApplicationContext(AppConfig::class.java)
    val myService = ctx.getBean<MyService>()
    myService.doStuff()
}

Oldin aytib o'tilganidek, AnnotationConfigApplicationContext faqat @Configuration annotatsiyasi bilan belgilangan sinflar bilan ishlash bilan cheklanmagan. Kiruvchi ma'lumot sifatida @Component yoki JSR-330 bilan belgilangan har qanday sinf berilishi mumkin, quyidagi misolda ko'rsatilganidek:

Java
public static void main(String[] args) {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(MyServiceImpl.class, Dependency1.class, Dependency2.class);
    MyService myService = ctx.getBean(MyService.class);
    myService.doStuff();
}
Kotlin
import org.springframework.beans.factory.getBean
fun main() {
    val ctx = AnnotationConfigApplicationContext(MyServiceImpl::class.java, Dependency1::class.java, Dependency2::class.java)
    val myService = ctx.getBean<MyService>()
    myService.doStuff()
}

Oldingi misolda MyServiceImpl, Dependency1 va Dependency2 Springning injektiv annotatsiyalaridan biri bo'lgan @Autowired kabilarni ishlatadi deb taxmin qilingan.

Registratsiya yordamida dasturiy konteyner yaratish register(Class<?>…​)

Siz AnnotationConfigApplicationContextni bo'sh argumentli konstruktor yordamida yaratishingiz va register() metodi yordamida uni sozlashingiz mumkin. Ushbu yondashuv AnnotationConfigApplicationContextni dasturiy yaratishda ayniqsa foydali. Quyidagi misol buni qanday amalga oshirish mumkinligini ko'rsatadi:

Java
public static void main(String[] args) {
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.register(AppConfig.class, OtherConfig.class);
    ctx.register(AdditionalConfig.class);
    ctx.refresh();
    MyService myService = ctx.getBean(MyService.class);
    myService.doStuff();
}
Kotlin
import org.springframework.beans.factory.getBean
fun main() {
    val ctx = AnnotationConfigApplicationContext()
    ctx.register(AppConfig::class.java, OtherConfig::class.java)
    ctx.register(AdditionalConfig::class.java)
    ctx.refresh()
    val myService = ctx.getBean<MyService>()
    myService.doStuff()
}

Komponentlarni skanerlashni scan(String…) yordamida yoqish

Komponentlarni skanerlashni yoqish uchun siz sinfni @Configuration bilan quyidagicha annotatsiya qilishingiz mumkin:

Java
@Configuration
@ComponentScan(basePackages = "com.acme") 
public class AppConfig  {
    // ...
}
  1. Bu annotatsiya komponentlarni skanerlashga imkon beradi.
Kotlin
@Configuration
@ComponentScan(basePackages = ["com.acme"]) 
class AppConfig  {
    // ...
}
  1. Bu annotatsiya komponentlarni skanerlashga imkon beradi.

Tajriba orttirgan Spring foydalanuvchilari context: nomi maydonidan XML e'loniga muqobil bo'lgan ekvivalentni bilishlari mumkin, quyidagi misolda ko'rsatilgan:

<beans>
    <context:component-scan base-package="com.acme"/>
</beans>

Tepardagi misolda com.acme paketi @Component bilan annotatsiya qilingan har qanday sinfni topish uchun skanerlanadi va bu sinflar bin ta'riflari sifatida Spring konteynerida ro'yxatdan o'tkaziladi. AnnotationConfigApplicationContext komponentlarni skanerlash funksiyasini taqdim etish uchun scan(String…​) metodini ochadi, quyidagi misolda ko'rsatilganidek:

Java
public static void main(String[] args) {
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.scan("com.acme");
    ctx.refresh();
    MyService myService = ctx.getBean(MyService.class);
}
Kotlin
fun main() {
    val ctx = AnnotationConfigApplicationContext()
    ctx.scan("com.acme")
    ctx.refresh()
    val myService = ctx.getBean<MyService>()
}
Eslatib o'ting, @Configuration sinflari @Component bilan meta-annotatsiyalangan, shuning uchun ular komponentlar skanerlashining nomzodlari sifatida ko'rib chiqiladi. Teparda ko'rsatilgan misolda, agar AppConfig com.acme paketida (yoki uning ostidagi har qanday paketda) e'lon qilingan deb faraz qilingan bo'lsa, u scan() chaqiruvi davomida ushlanadi. refresh()dan so'ng, uning barcha @Bean bilan annotatsiyalangan metodlari qayta ishlanadi va konteynerda bin ta'riflari sifatida ro'yxatdan o'tkaziladi.

Web-ilovalarni qo'llab-quvvatlash AnnotationConfigWebApplicationContext yordamida

WebApplicationContext varianti AnnotationConfigApplicationContext sinfida AnnotationConfigWebApplicationContext yordamida foydalanilishi mumkin. Siz ushbu amalga oshirilishni Spring ContextLoaderListener servlet dinlovi yoki Spring MVC DispatcherServlet va hokazolarni sozlashda ishlatishingiz mumkin. Quyidagi web.xml parchasi odatiy Spring MVC veb-ilovasi konfiguratsiyasini ko'rsatadi (e'tibor bering, kontekst parametrlarini contextClass va ilova parametrlarini ishlatishga):

<web-app>
    <!-- AnnotationConfigWebApplicationContext'dan foydalanish uchun ContextLoaderListener sozlash 
        XmlWebApplicationContext o'rniga -->
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
    </context-param>
    <!-- Konfiguratsiya joylari vergul yoki bo'sh joylar bilan ajratilgan bitta yoki bir nechta 
        to'liq sinf nomlaridan iborat bo'ladi - @Configuration bilan annotatsiyalangan. 
        To'liq paket nomlari ham bo'lishi mumkin -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.acme.AppConfig</param-value>
    </context-param>
    <!-- ContextLoaderListener yordamida ildiz ilova kontekstini yuklashni amalga oshiring -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- Spring MVC'da DispatcherServletni e'lon qiling, odatdagidek -->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- DispatcherServletni AnnotationConfigWebApplicationContext'dan foydalanish 
            uchun konfiguratsiya qilish -->
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>
                org.springframework.web.context.support.AnnotationConfigWebApplicationContext
            </param-value>
        </init-param>
        <!-- Yana, konfiguratsiya joylari @Configuration bilan annotatsiyalangan sinf 
            to'liq nomlaridan iborat bo'lishi kerak -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>com.acme.web.MvcConfig</param-value>
        </init-param>
    </servlet>
    <!-- barcha /app/* so'rovlari dispatcher servlet'ga mos kelishi uchun -->
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/app/*</url-pattern>
    </servlet-mapping>
</web-app>
Dasturiy hodisalar uchun GenericWebApplicationContext AnnotationConfigWebApplicationContext o'rniga muqobil bo'lishi mumkin. Qo'shimcha ma'lumot uchun javadocga qarang GenericWebApplicationContext.
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION