Rozdiel medzi BeanFactory a ApplicationContext

1. Prehľad

Jarný rámec sa dodáva s dvoma kontajnermi MOV - BeanFactory a ApplicationContext. The BeanFactory je najzákladnejšia verzia kontajnerov IOC a ApplicationContext rozširuje vlastnosti BeanFactory.

V tomto rýchlom návode pochopíme významné rozdiely medzi týmito dvoma kontajnermi IOC na praktických príkladoch.

2. Lenivé načítanie vs. nedočkavé načítanie

BeanFactory nakladá fazuľu na požiadanie, zatiaľ čo ApplicationContext načíta všetky fazule pri štarte. Teda BeanFactory je ľahký v porovnaní s ApplicationContext. Poďme to pochopiť na príklade.

2.1. Lenivé načítanie pomocou BeanFactory

Predpokladajme, že máme zavolanú triedu fazule singleton Študent jednou metódou:

public class Student {public static boolean isBeanInstantiated = false; public void postConstruct () {setBeanInstantiated (true); } // štandardní zakladatelia a obstarávatelia}

Definujeme postConstruct () metóda ako metóda init v našom BeanFactory konfiguračný súbor, ioc-container-difference-example.xml:

Teraz napíšeme testovací prípad, ktorý vytvorí a BeanFactory skontrolovať, či načíta Študent fazuľa:

@Test public void whenBFInitialized_thenStudentNotInitialized () {Resource res = new ClassPathResource ("ioc-container-difference-example.xml"); BeanFactory factory = nový XmlBeanFactory (res); assertFalse (Student.isBeanInstantiated ()); }

Tu, the Študent objekt nie je inicializovaný. Inými slovami, len BeanFactory je inicializovaný. Fazuľa definovaná v našom BeanFactory sa načítajú, iba keď vyslovene zavoláme getBean () metóda.

Poďme skontrolovať inicializáciu našej Študent fazuľa, kde manuálne voláme getBean () metóda:

@Test public void whenBFInitialized_thenStudentInitialized () {Resource res = new ClassPathResource ("ioc-container-difference-example.xml"); BeanFactory factory = nový XmlBeanFactory (res); Študent študent = (Študent) factory.getBean ("študent"); assertTrue (Student.isBeanInstantiated ()); }

Tu je Študent fazuľa sa úspešne načíta. Preto je BeanFactory fazuľu naloží iba ak je to potrebné.

2.2. Nedočkavé načítanie s ApplicationContext

Teraz poďme ApplicationContext v mieste BeanFactory.

Budeme iba definovať ApplicationContext, a okamžite načíta všetky fazule pomocou stratégie nedočkavého načítania:

@Test public void whenAppContInitialized_thenStudentInitialized () {ApplicationContext context = new ClassPathXmlApplicationContext ("ioc-container-difference-example.xml"); assertTrue (Student.isBeanInstantiated ()); }

Tu je Študent objekt je vytvorený aj napriek tomu, že sme volali getBean () metóda.

ApplicationContext je považovaný za ťažký kontajner IOC, pretože jeho stratégia nedočkavého načítania načíta všetky fazule pri štarte. BeanFactory je v porovnaní s nízkou hmotnosťou a môže byť užitočný v systémoch s obmedzenou pamäťou. Napriek tomu uvidíme v ďalších častiach prečo ApplicationContext je preferovaný pre väčšinu prípadov použitia.

3. Funkcie podnikových aplikácií

ApplicationContext zvyšuje BeanFactory v štýle viac zameranom na rámec a poskytuje niekoľko funkcií vhodných pre podnikové aplikácie.

Napríklad to poskytuje správy (i18n alebo internacionalizácia) funkčnosť, zverejnenie udalosti funkčnosť, anotácia závislosť injekciea ľahká integrácia s funkciami Spring AOP.

Okrem toho ApplicationContext podporuje takmer všetky typy rozsahov fazule, ale BeanFactory podporuje iba dva rozsahy - Singleton a Prototyp. Preto je vždy lepšie použiť ApplicationContext pri vytváraní zložitých podnikových aplikácií.

4. Automatická registrácia BeanFactoryPostProcessor a BeanPostProcessor

The ApplicationContext automaticky zaregistruje BeanFactoryPostProcessor a BeanPostProcessor pri štarte. Na druhej strane BeanFactory neregistruje tieto rozhrania automaticky.

4.1. Registrácia v BeanFactory

Aby sme to pochopili, napíšme dve triedy.

Po prvé, máme CustomBeanFactoryPostProcessor triedy, ktorá implementuje BeanFactoryPostProcessor:

verejná trieda CustomBeanFactoryPostProcessor implementuje BeanFactoryPostProcessor {private static boolean isBeanFactoryPostProcessorRegistered = false; @Override public void postProcessBeanFactory (ConfigurableListableBeanFactory beanFactory) {setBeanFactoryPostProcessorRegistered (true); } // štandardní zakladatelia a obstarávatelia}

Tu sme prepísali postProcessBeanFactory () spôsob kontroly jeho registrácie.

Po druhé, máme ďalšiu triedu, CustomBeanPostProcessor, ktorý realizuje BeanPostProcessor:

verejná trieda CustomBeanPostProcessor implementuje BeanPostProcessor {private static boolean isBeanPostProcessorRegistered = false; @Override public Object postProcessBeforeInitialization (objekt bean, reťazec beanName) {setBeanPostProcessorRegistered (true); spätná fazuľa; } // štandardní zakladatelia a obstarávatelia}

Tu sme prepísali postProcessBeforeInitialization () spôsob kontroly jeho registrácie.

Tiež sme nakonfigurovali obe triedy v našom ioc-container-difference-example.xml konfiguračný súbor:

Pozrime sa na testovací prípad, ktorý skontroluje, či sú tieto dve triedy zaregistrované automaticky počas spustenia:

@Test public void whenBFInitialized_thenBFPProcessorAndBPProcessorNotRegAutomatically () {Resource res = new ClassPathResource ("ioc-container-difference-example.xml"); ConfigurableListableBeanFactory factory = nový XmlBeanFactory (res); assertFalse (CustomBeanFactoryPostProcessor.isBeanFactoryPostProcessorRegistered ()); assertFalse (CustomBeanPostProcessor.isBeanPostProcessorRegistered ()); }

Ako vidíme z nášho testu, automatická registrácia sa nekonala.

Teraz sa pozrime na testovací prípad, ktorý ich manuálne pridá do súboru BeanFactory:

@Test public void whenBFPostProcessorAndBPProcessorRegisteredManually_thenReturnTrue () {Resource res = new ClassPathResource ("ioc-container-difference-example.xml"); ConfigurableListableBeanFactory factory = nový XmlBeanFactory (res); CustomBeanFactoryPostProcessor beanFactoryPostProcessor = nový CustomBeanFactoryPostProcessor (); beanFactoryPostProcessor.postProcessBeanFactory (továreň); assertTrue (CustomBeanFactoryPostProcessor.isBeanFactoryPostProcessorRegistered ()); CustomBeanPostProcessor beanPostProcessor = nový CustomBeanPostProcessor (); factory.addBeanPostProcessor (beanPostProcessor); Študent študent = (Študent) factory.getBean ("študent"); assertTrue (CustomBeanPostProcessor.isBeanPostProcessorRegistered ()); }

Tu sme použili postProcessBeanFactory () spôsob registrácie CustomBeanFactoryPostProcessor a addBeanPostProcessor () spôsob registrácie CustomBeanPostProcessor. V tomto prípade sa obaja úspešne zaregistrujú.

4.2. Registrácia v ApplicationContext

Ako sme už uviedli, ApplicationContext zaregistruje obe triedy automaticky bez nutnosti písania dodatočného kódu.

Overme toto správanie v teste jednotky:

@Test public void whenAppContInitialized_thenBFPostProcessorAndBPostProcessorRegisteredAutomatically () {ApplicationContext context = new ClassPathXmlApplicationContext ("ioc-container-difference-example.xml"); assertTrue (CustomBeanFactoryPostProcessor.isBeanFactoryPostProcessorRegistered ()); assertTrue (CustomBeanPostProcessor.isBeanPostProcessorRegistered ()); }

Ako vidíme, automatická registrácia oboch tried je úspešná v tomto prípade.

Preto vždy sa odporúča použiť ApplicationContext pretože jar 2.0 (a vyššia) sa veľmi používa BeanPostProcessor.

To tiež stojí za zmienku ak pouzivas planinu BeanFactory, potom funkcie ako transakcie a AOP nebudú účinné (aspoň nie bez napísania ďalších riadkov kódu). To môže viesť k zámene, pretože s konfiguráciou nebude nič vyzerať zle.

5. Záver

V tomto článku sme videli kľúčové rozdiely medzi nimi ApplicationContext a BeanFactory s praktickými príkladmi.

The ApplicationContext prichádza s pokročilými funkciami, vrátane niekoľkých, ktoré sú zamerané na podnikové aplikácie, zatiaľ čo BeanFactory prichádza iba so základnými funkciami. Preto sa všeobecne odporúča používať ApplicationContext, a mali by sme použiť BeanFactory iba ak je kritická spotreba pamäte.

Ako vždy je kód článku k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found