Különbség a BeanFactory és az ApplicationContext között

1. Áttekintés

A Spring Framework két NOB konténert tartalmaz - BeanFactory és ApplicationContext. A BeanFactory a NOB konténerek legalapvetőbb változata, és a ApplicationContext kiterjeszti a BeanFactory.

Ebben a gyors bemutatóban gyakorlati példákkal fogjuk megérteni a két NOB konténer közötti jelentős különbségeket.

2. Lusta betöltés vs lelkes betöltés

BeanFactory igény szerint babot tölt be, míg ApplicationContext indításkor az összes babot betölti. Így, BeanFactory könnyű ahhoz képest ApplicationContext. Értsük meg egy példával.

2.1. Lusta betöltés BeanFactory

Tegyük fel, hogy van egy szinglik bab osztályunk Diák egy módszerrel:

public class Student {public static boolean isBeanInstantiated = hamis; public void postConstruct () {setBeanInstantiated (true); } // szabványos beállítók és szerelők}

Meghatározzuk a postConstruct () módszer, mint a init-módszer miénkben BeanFactory konfigurációs fájl, ioc-container-különbség-példa.xml:

Írjunk egy tesztesetet, amely létrehozza a BeanFactory ellenőrizni, hogy betölti-e a Diák bab:

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

Itt, a Diák az objektum nincs inicializálva. Más szavakkal, csak a BeanFactory inicializálva van. A mi babunkban definiált bab BeanFactory csak akkor töltődik be, ha kifejezetten meghívjuk a getBean () módszer.

Ellenőrizzük az inicializálást Diák bab, ahol manuálisan hívjuk a getBean () módszer:

@Test public void whenBFInitialized_thenStudentInitialized () {Resource res = new ClassPathResource ("ioc-container-difference-example.xml"); BeanFactory gyár = new XmlBeanFactory (res); Hallgató diák = (Tanuló) gyár.getBean ("hallgató"); assertTrue (Student.isBeanInstantiated ()); }

Itt a Diák babot sikeresen betölt. Ezért a BeanFactory a babot csak akkor tölti be, amikor szükséges.

2.2. Szívesen töltődik ApplicationContext

Most használjuk ApplicationContext helyén BeanFactory.

Csak meghatározzuk ApplicationContext, és azonnal betölti az összes babot egy lelkes rakodási stratégia alkalmazásával:

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

Itt a Diák az objektum akkor is létrejön, ha még nem hívtuk a getBean () módszer.

ApplicationContext nehéz NOB konténernek tekinthető, mert buzgó rakodási stratégiája az összes babot megrakja indításkor. BeanFactory könnyű ahhoz képest, és hasznos lehet a memória korlátozott rendszerekben. Mindazonáltal, a következő szakaszokban meglátjuk, miért ApplicationContext előnyös a legtöbb felhasználási esetben.

3. Vállalati alkalmazás jellemzői

ApplicationContext fokozza BeanFactory keretrendszer-orientáltabb stílusban, és számos olyan szolgáltatást kínál, amelyek alkalmasak a vállalati alkalmazások számára.

Például azt üzenetküldést biztosít (i18n vagy nemzetközivé válás) funkcionalitás, rendezvény kiadványa funkcionalitás, annotáció-alapú függőségi injekció, és könnyű integráció a Spring AOP funkcióival.

Ettől eltekintve a ApplicationContext szinte minden típusú bab hatókört támogat, de a BeanFactory csak két hatókört támogat - Szingli és Prototípus. Ezért mindig előnyösebb használni ApplicationContext komplex vállalati alkalmazások felépítésekor.

4. Automatikus regisztráció BeanFactoryPostProcessor és BeanPostProcessor

A ApplicationContext automatikusan regisztrál BeanFactoryPostProcessor és BeanPostProcessor indításkor. Másrészt a BeanFactory nem regisztrálja ezeket az interfészeket automatikusan.

4.1. Regisztráció itt: BeanFactory

Hogy megértsük, írjunk két osztályt.

Először is megvan a CustomBeanFactoryPostProcessor osztály, amely végrehajtja a BeanFactoryPostProcessor:

public class CustomBeanFactoryPostProcessor implementálja a BeanFactoryPostProcessor {private static boolean isBeanFactoryPostProcessorRegistered = false; @Override public void postProcessBeanFactory (ConfigurableListableBeanFactory beanFactory) {setBeanFactoryPostProcessorRegistered (true); } // szabványos beállítók és szerelők}

Itt felülírtuk a postProcessBeanFactory () módszer a regisztráció ellenőrzésére.

Másodszor van egy másik osztályunk, CustomBeanPostProcessor, amely végrehajtja BeanPostProcessor:

public class CustomBeanPostProcessor implementálja a BeanPostProcessor {private static logikai isBeanPostProcessorRegistered = false; @Orride public Object postProcessBeforeInitialization (Object bean, String beanName) {setBeanPostProcessorRegistered (true); visszatérő bab; } // szabványos beállítók és szerelők}

Itt felülírtuk a postProcessBeforeInitialization () módszer a regisztráció ellenőrzésére.

Ezenkívül mindkét osztályt konfiguráltuk a mi ioc-container-különbség-példa.xml konfigurációs fájl:

Lássunk egy tesztesetet annak ellenőrzésére, hogy ez a két osztály automatikusan regisztrálásra került-e az indítás során:

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

Mint a tesztünkből kiderül, automatikus regisztráció nem történt meg.

Most nézzünk meg egy tesztesetet, amely manuálisan hozzáadja őket a BeanFactory:

@Test public void whenBFPostProcessorAndBPProcessorRegisteredManually_thenReturnTrue () {Resource res = new ClassPathResource ("ioc-container-difference-example.xml"); ConfigurableListableBeanFactory gyár = new XmlBeanFactory (res); CustomBeanFactoryPostProcessor beanFactoryPostProcessor = new CustomBeanFactoryPostProcessor (); beanFactoryPostProcessor.postProcessBeanFactory (gyár); assertTrue (CustomBeanFactoryPostProcessor.isBeanFactoryPostProcessorRegistered ()); CustomBeanPostProcessor beanPostProcessor = új CustomBeanPostProcessor (); gyár.addBeanPostProcessor (beanPostProcessor); Hallgató diák = (Tanuló) gyár.getBean ("hallgató"); assertTrue (CustomBeanPostProcessor.isBeanPostProcessorRegistered ()); }

Itt használtuk a postProcessBeanFactory () módszer a regisztrációhoz CustomBeanFactoryPostProcessor és a addBeanPostProcessor () módszer a regisztrációhoz CustomBeanPostProcessor. Mindketten sikeresen regisztrálnak ebben az esetben.

4.2. Regisztráció itt: ApplicationContext

Amint azt korábban megjegyeztük, ApplicationContext automatikusan regisztrálja mindkét osztályt anélkül, hogy további kódot írna.

Ellenőrizzük ezt a viselkedést egységteszten:

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

Ahogy látjuk, mindkét osztály automatikus regisztrációja sikeres ebben az esetben.

Ebből kifolyólag, mindig tanácsos használni ApplicationContext mert a 2.0 (és újabb) tavasz erősen használja BeanPostProcessor.

Érdemes ezt is megjegyezni ha a síkságot használja BeanFactory, akkor az olyan szolgáltatások, mint a tranzakciók és az AOP, nem lépnek életbe (legalábbis anélkül, hogy extra kódsorokat írna). Ez zavart okozhat, mert semmi nem fog rosszul nézni a konfigurációval.

5. Következtetés

Ebben a cikkben a legfontosabb különbségeket láttuk ApplicationContext és BeanFactory gyakorlati példákkal.

A ApplicationContext fejlett funkciókkal rendelkezik, köztük több, amely a vállalati alkalmazásokhoz igazodik, míg a BeanFactory csak alapvető funkciókkal rendelkezik. Ezért általában ajánlott a ApplicationContext, és használnunk kellene BeanFactory csak akkor, ha a memóriafogyasztás kritikus.

Mint mindig, a cikk kódja elérhető a GitHubon.