ApplicationContext
BeanFactory vs ApplicationContext, XML config, Java config, annotation-based config
ApplicationContext
1. Definíció
Az ApplicationContext a Spring Framework központi interfésze, amely a teljes IoC container funkcionalitást biztosítja. A BeanFactory interfész leszármazottja, de azon túlmutatva integrált AOP-támogatást, nemzetköziesítést (i18n), eseménykezelést és environment-absztrakciót is kínál. A legtöbb Spring alkalmazás az ApplicationContext-et használja a BeanFactory helyett, mert az éles üzemhez szükséges szolgáltatások mind itt érhetők el.
A Spring Boot alkalmazásokban az ApplicationContext-et a SpringApplication.run() hozza létre automatikusan — általában AnnotationConfigServletWebServerApplicationContext típussal web alkalmazásoknál.
2. Alapfogalmak
BeanFactory vs ApplicationContext
| Jellemző | BeanFactory | ApplicationContext |
|---|---|---|
| Bean létrehozás | Lazy (első lekéréskor) | Eager (induláskor singleton-ok) |
| Eseménykezelés | ❌ | ✅ ApplicationEventPublisher |
| i18n (MessageSource) | ❌ | ✅ |
| AOP integráció | Kézi | Automatikus |
| BeanPostProcessor regisztráció | Kézi | Automatikus |
| Environment / Profile | ❌ | ✅ |
| ResourceLoader | Alapszintű | Fejlett (classpath, file, URL) |
A BeanFactory lightweight container, amely csak a bean-ek példányosítását és DI-t végzi. Az ApplicationContext mindent tartalmaz, amit a BeanFactory, plusz enterprise-szintű szolgáltatásokat.
Főbb ApplicationContext implementációk
AnnotationConfigApplicationContext— Java config (@Configurationosztályok) standalone alkalmazásbanClassPathXmlApplicationContext— XML konfiguráció classpath-rólGenericWebApplicationContext— Web környezet, servlet container integrációAnnotationConfigServletWebServerApplicationContext— Spring Boot web alkalmazás (alapértelmezett)
Konfiguráció típusok
XML-alapú — A klasszikus megközelítés, <beans> gyökérelem, <bean> definíciók:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="...">
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<property name="jdbcUrl" value="jdbc:h2:mem:test"/>
</bean>
</beans>
Java config — @Configuration + @Bean:
@Configuration
public class AppConfig {
@Bean
public DataSource dataSource() {
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl("jdbc:h2:mem:test");
return ds;
}
}
Annotáció-alapú — @ComponentScan + sztereotíp annotációk (@Component, @Service, @Repository):
@Configuration
@ComponentScan("com.example")
public class AppConfig {}
Gyakorlatban a legtöbb Spring Boot projekt a Java config + annotáció-alapú megközelítés kombinációját használja. XML config legacy kódban fordul elő.
3. Gyakorlati használat
Context indítás standalone alkalmazásban
// Java config
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = ctx.getBean(UserService.class);
// XML config (legacy)
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Spring Boot alkalmazás
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(MyApp.class, args);
// ctx automatikusan elérhető, ritkán kell kézzel lekérni bean-t
}
}
Environment és Profile-ok
@Configuration
@Profile("production")
public class ProdConfig {
@Bean
public DataSource dataSource() {
// production DataSource
}
}
Aktiválás: spring.profiles.active=production (application.properties vagy JVM arg).
Eseménykezelés
// Esemény publikálás
@Service
public class OrderService {
private final ApplicationEventPublisher publisher;
public OrderService(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public void placeOrder(Order order) {
// üzleti logika
publisher.publishEvent(new OrderPlacedEvent(order));
}
}
// Esemény fogadás
@Component
public class NotificationListener {
@EventListener
public void onOrderPlaced(OrderPlacedEvent event) {
// értesítés küldése
}
}
i18n (MessageSource)
@Autowired
private MessageSource messageSource;
String msg = messageSource.getMessage("greeting", null, Locale.forLanguageTag("hu"));
4. Kód példák
Teljes Java config alkalmazás
@Configuration
@ComponentScan("com.example")
@PropertySource("classpath:app.properties")
public class AppConfig {
@Value("${app.name}")
private String appName;
@Bean
public AppInfo appInfo() {
return new AppInfo(appName);
}
}
Több config összekapcsolása
@Configuration
@Import({DataConfig.class, SecurityConfig.class})
public class RootConfig {}
Context hierarchia (parent-child)
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(SharedConfig.class);
AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
child.setParent(parent);
child.register(WebConfig.class);
child.refresh();
// child context eléri a parent bean-jeit, fordítva nem
ResourceLoader használat
@Service
public class TemplateService {
private final ResourceLoader resourceLoader;
public TemplateService(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
public String loadTemplate(String path) throws IOException {
Resource resource = resourceLoader.getResource("classpath:" + path);
return new String(resource.getInputStream().readAllBytes());
}
}
5. Trade-offok
| Szempont | Előny | Hátrány |
|---|---|---|
| Eager initialization (singleton) | Hibák induláskor kiderülnek (fail-fast) | Lassabb indulás sok bean esetén |
| Java config vs XML | Típusbiztos, IDE refactoring | Bonyolultabb @Conditional logika |
| XML config | Deklaratív, kódon kívüli módosítás | Verbose, nincs compiler ellenőrzés |
| Annotáció-alapú config | Minimális boilerplate | Szétszórt konfiguráció, nehéz áttekinteni |
| @ComponentScan | Automatikus, kevés kód | Nem látszik, mi kerül a context-be |
| Explicit @Bean | Teljes kontroll, dokumentált | Több kód, karbantartás |
Mikor melyik megközelítés?
- Új projekt: Java config + annotációk (Spring Boot default)
- Külső library bean:
@Beanmetódus@Configurationosztályban - Legacy integráció:
@ImportResource("legacy-context.xml") - Feltételes bean:
@Conditional*annotációk Java config-ban
6. Gyakori hibák
❌ Context manuális bezárás nélkül (standalone app)
// ROSSZ — erőforrás szivárgás
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
// használat...
// @PreDestroy callback-ek nem futnak le
// JÓ — try-with-resources
try (var ctx = new AnnotationConfigApplicationContext(AppConfig.class)) {
ctx.getBean(MyService.class).doWork();
} // @PreDestroy automatikusan meghívódik
❌ BeanFactory használata ApplicationContext helyett
// ROSSZ — nincs AOP, nincs Event, nincs BeanPostProcessor auto-regisztráció
BeanFactory factory = new DefaultListableBeanFactory();
// JÓ — használj ApplicationContext-et
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
❌ Context refresh többszöri meghívása
// ROSSZ — duplikált bean-ek, memória szivárgás
ctx.refresh();
ctx.refresh();
❌ Rossz profile aktiválás
// ROSSZ — a profile-t a context refresh előtt kell beállítani
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.refresh();
ctx.getEnvironment().setActiveProfiles("prod"); // Nincs hatása!
// JÓ
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("prod");
ctx.register(AppConfig.class);
ctx.refresh();
7. Mélyebb összefüggések
Context lifecycle
- Bean definition betöltés —
@Configurationosztályok, XML fájlok parse-olása - BeanFactoryPostProcessor futtatás — bean definíciók módosítása (pl.
PropertySourcesPlaceholderConfigurer) - Bean példányosítás — singleton bean-ek eager létrehozása
- BeanPostProcessor futtatás — AOP proxy, @Autowired feloldás
- Context ready —
ContextRefreshedEventpublikálása - Működés — bean-ek használata
- Context close —
ContextClosedEvent, @PreDestroy callback-ek
BeanFactoryPostProcessor vs BeanPostProcessor
| Aspektus | BeanFactoryPostProcessor | BeanPostProcessor |
|---|---|---|
| Mikor fut? | Bean definíciók betöltése után, példányosítás előtt | Minden egyes bean példányosítása után |
| Mit módosít? | Bean definíciókat (metaadatok) | Bean példányokat |
| Tipikus használat | Property placeholder feloldás, bean definíció módosítás | AOP proxy, @Autowired, @PostConstruct |
Context hierarchia (parent-child)
A Spring MVC klasszikus modellje: root context (service, repository bean-ek) és servlet context (controller-ek, view resolver-ek). A gyerek context látja a szülő bean-jeit, de fordítva nem. Spring Boot-ban ez egyszerűsödött — jellemzően egy flat context van.
@Configuration osztályok CGLIB proxy-ja
A @Configuration osztályokat a Spring CGLIB proxy-val tölti be. Ennek köszönhető, hogy a @Bean metódusok inter-bean referenciái (egy @Bean metódus meghív egy másikat) singleton szemantikát tartanak. Ha @Configuration(proxyBeanMethods = false) (lite mode), ez a viselkedés kikapcsol.
@Configuration
public class AppConfig {
@Bean
public ServiceA serviceA() {
return new ServiceA(commonDep()); // CGLIB: singleton-t ad vissza
}
@Bean
public ServiceB serviceB() {
return new ServiceB(commonDep()); // CGLIB: UGYANAZT a példányt adja
}
@Bean
public CommonDep commonDep() {
return new CommonDep();
}
}
8. Interjúkérdések
Mi a különbség a BeanFactory és az ApplicationContext között? A BeanFactory az alapszintű DI container (lazy init), az ApplicationContext mindent tartalmaz + event, i18n, AOP, BeanPostProcessor auto-regisztráció, Environment.
Milyen ApplicationContext implementációkat ismersz?
AnnotationConfigApplicationContext,ClassPathXmlApplicationContext,GenericWebApplicationContext, Spring Boot:AnnotationConfigServletWebServerApplicationContext.Mi a különbség Java config és annotáció-alapú config között? Java config: explicit
@Beanmetódusok@Configurationosztályban. Annotáció-alapú:@ComponentScan+ sztereotíp annotációk (@Component,@Service). Gyakorlatban kombinálják őket.Hogyan működik a @Configuration CGLIB proxy? A Spring CGLIB subclass-t hoz létre a
@Configurationosztályból. Így az inter-bean referenciák (egy@Beanmetódus meghív másikat) mindig a singleton cache-ből adják a példányt.proxyBeanMethods = falsekikapcsolja.Mi a context lifecycle sorrendje? Bean definition load → BeanFactoryPostProcessor → Singleton instantiation → BeanPostProcessor → ContextRefreshedEvent → Usage → ContextClosedEvent → @PreDestroy.
Mikor használnál XML config-ot 2024-ben? Legacy integráció, third-party framework kényszer, vagy ha a konfigurációt kódon kívül kell módosítani. Új projektben Java config az ajánlott.
Mi a context hierarchia és mire jó? Parent-child context: a gyerek látja a szülő bean-jeit, de fordítva nem. Klasszikus Spring MVC-ben root (service) és servlet (web) context-ek. Spring Boot-ban flat context a jellemző.
9. Szószedet
| Fogalom | Jelentés |
|---|---|
| BeanFactory | Alapszintű IoC container interfész, lazy bean init |
| ApplicationContext | Teljes funkcionalitású container (BeanFactory + enterprise szolgáltatások) |
| @Configuration | Java-based konfigurációs osztály, CGLIB proxy-val |
| @ComponentScan | Automatikus bean regisztráció csomagok szkennelésével |
| @PropertySource | Külső property fájl betöltése az Environment-be |
| @Import | Több konfigurációs osztály összekapcsolása |
| @Profile | Bean/konfiguráció feltételes aktiválása profil alapján |
| MessageSource | i18n felület, lokalizált üzenetek feloldása |
| ApplicationEventPublisher | Eseményeket publikáló interfész |
| BeanFactoryPostProcessor | Bean definíciók módosítása példányosítás előtt |
| ContextRefreshedEvent | Esemény a context teljes inicializálása után |
| proxyBeanMethods | @Configuration attribútum, CGLIB proxy be/kikapcsolás |
10. Gyorsreferencia
BeanFactory → Lightweight, lazy init, csak DI
ApplicationContext → BeanFactory + AOP + Event + i18n + Environment
Konfigurációs stílusok:
XML: ClassPathXmlApplicationContext("beans.xml")
Java: AnnotationConfigApplicationContext(AppConfig.class)
Boot: SpringApplication.run(MyApp.class, args)
Context lifecycle:
Def load → BFPP → Instantiate → BPP → @PostConstruct → Ready → Close → @PreDestroy
@Configuration:
CGLIB proxy → inter-bean ref = singleton
proxyBeanMethods=false → lite mode, nincs proxy
Gyakori implementációk:
AnnotationConfigApplicationContext standalone + Java config
ClassPathXmlApplicationContext standalone + XML
AnnotationConfigServletWebServerAC Spring Boot web
Context hierarchia:
child.setParent(parent)
child → parent bean-ek láthatók
parent → child bean-ek NEM láthatók
Tipikus hibák:
✗ BeanFactory használata ApplicationContext helyett
✗ Context bezárás elfelejtése (standalone)
✗ Profile beállítás refresh() után
✗ Többszöri refresh() meghívás
🎮 Játékok
10 kérdés