1 Interfaces
1-1 Basic Interface Description
Spring Boot startup source code
package com.village.dog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Application {
private static final Logger logging = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class,args);
}
}

BeanFactory interface: The root interface for accessing a Spring container.
Description: An object implementing BeanFactory holds multiple bean definitions, each uniquely identified by a string name.
ApplicationContext interface: The core interface for providing configuration to an application.
| Supported Feature | Corresponding Parent Interface |
|---|---|
| Factory method for accessing application components | org.springframework.beans.factory.ListableBeanFactory |
| Ability to load file resources | org.springframework.core.io.ResourceLoader |
| Ability to publish events to registered listeners | ApplicationEventPublisher |
| Ability to resolve messages with i18n support | MessageSource |
Note: As seen in the class diagram, the ApplicationContext interface extends BeanFactory and also inherits many other interfaces.
In Java, an interface can extend one or more interfaces using the
extendskeyword.
1-2 BeanFactory Implementation Classes

DefaultListableBeanFactory: The default implementation class in Spring.
- Parent class:
DefaultSingletonBeanRegistry— a generic registry for shared bean instances, allowing retrieval of singleton objects by bean name.
// Description: DefaultSingletonBeanRegistry defines a ConcurrentHashMap holding all singleton objects.
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
}
Requirement: Print specific singleton objects from the "singleton objects map."
package com.village.dog;
import org.springframework.stereotype.Component;
// Spring Boot defaults to singleton scope
@Component
public class Component1 {
}
@Component
public class Component2 {
}
package com.village.dog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import java.lang.reflect.Field;
import java.util.Map;
@SpringBootApplication
public class Application {
private static final Logger logging = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
// Use reflection to obtain the ConcurrentHashMap storing singleton objects, and print the two injected components: Component1 and Component2.
Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
singletonObjects.setAccessible(true);
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
Map<String, Object> map = (Map<String, Object>) singletonObjects.get(beanFactory);
map.entrySet().stream()
.filter(e -> e.getKey().startsWith("component"))
.forEach(e -> System.out.println(e.getKey() + "=" + e.getValue()));
}
}
Output:
component1=com.village.dog.Component1@601cbd8c
component2=com.village.dog.Component2@7180e701
1-3 ApplicationContext Interface Features
The parent interfaces of ApplicationContext (from Figure 2) include:
ListableBeanFactoryandHierarchicalBeanFactory: extensions ofBeanFactory.MessageSource: strategy interface for message resolution, supporting parameterization and internationalization.EnvironmentCapable: provides environment information, including configuration from YAML, XML, and other file types.ApplicationEventPublisher: ability to publish event objects.ResourcePatternResolver: ability to resolve resources using wildcards.
Note: Beyond the basic ability to retrieve bean instances, ApplicationContext supports four additional capabilities: internationalization, environment information retrieval, wildcard-based resource resolution, and event publishing.
Test code for the four extension features:
package com.village.dog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class Component1 {
private static final Logger log = LoggerFactory.getLogger(Component1.class);
@EventListener
public void testMonitor(UserRegisterEvent event) {
log.info("Received message: {}", event);
}
}
package com.village.dog;
import org.springframework.context.ApplicationEvent;
public class UserRegisterEvent extends ApplicationEvent {
public UserRegisterEvent(Object source) {
super(source);
}
}
package com.village.dog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.Resource;
import java.io.IOException;
import java.util.Locale;
@SpringBootApplication
public class ApplicationExtension {
private static final Logger logging = LoggerFactory.getLogger(ApplicationExtension.class);
public static void main(String[] args) throws IOException {
ConfigurableApplicationContext context = SpringApplication.run(ApplicationExtension.class, args);
// 1) Internationalization: Inherited from MessageSource
System.out.println("1 Testing internationalization");
System.out.println(context.getMessage("hi", null, Locale.CHINA));
System.out.println(context.getMessage("hi", null, Locale.ENGLISH));
System.out.println(context.getMessage("hi", null, Locale.JAPANESE));
System.out.println();
// 2) Resource retrieval
System.out.println("2 Testing resource retrieval");
Resource[] resources = context.getResources("classpath:application.properties");
for (Resource resource : resources) {
System.out.println(resource);
}
// Using wildcards to get paths of files named spring.factories from JARs
Resource[] re = context.getResources("classpath*:META-INF/spring.factories");
for (Resource resource : re) {
System.out.println(resource);
}
System.out.println();
// 3) Environment information retrieval: Inherited from EnvironmentCapable
System.out.println("3 Testing environment info retrieval");
System.out.println(context.getEnvironment().getProperty("JAVA_HOME"));
System.out.println(context.getEnvironment().getProperty("server.port"));
System.out.println();
// 4) Event publishing: Inherited from ApplicationEventPublisher
System.out.println("4 Testing event publishing");
context.publishEvent(new UserRegisterEvent(context));
}
}
Output:
1 Testing internationalization
你好
Hello
こんにちは
2 Testing resource retrieval
class path resource [application.properties]
URL [jar:file:/C:/Users/Administrator/.m2/repository/org/springframework/boot/spring-boot/2.5.5/spring-boot-2.5.5.jar!/META-INF/spring.factories]
URL [jar:file:/C:/Users/Administrator/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.5.5/spring-boot-autoconfigure-2.5.5.jar!/META-INF/spring.factories]
URL [jar:file:/C:/Users/Administrator/.m2/repository/org/springframework/spring-beans/5.3.10/spring-beans-5.3.10.jar!/META-INF/spring.factories]
URL [jar:file:/C:/Users/Administrator/.m2/repository/org/springframework/boot/spring-boot-test/2.5.5/spring-boot-test-2.5.5.jar!/META-INF/spring.factories]
3 Testing environment info retrieval
C:\Program Files\Java\jdk1.8.0_131
9006
4 Testing event publishing
[2022-05-17 16:03:06] [INFO ] -- Received message: com.village.dog.UserRegisterEvent[source=org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@67080771]
2 Implementation Classes
2-1 BeanFactory Implementation Characteristics
- Characteristic 1: As a low-level class, it does not support the following features (unlike ApplicationContext):
- Does not automatically invoke BeanFactory post-processors.
- Does not automatically add Bean post-processors (for resolving
@Autowired,@Resourcedependency injection). - Does not automatically initialize singletons.
- Does not resolve
${}or#{}(EL expressions).
- Characteristic 2: Bean post-processors support ordering.
Demonstration code for BeanFactory characteristics:
package com.village.dog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
public class TestBeanFactory {
private static void printBeanDefinitions(DefaultListableBeanFactory beanFactory) {
for (String name : beanFactory.getBeanDefinitionNames()) {
System.out.println(name);
}
System.out.println();
}
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
AbstractBeanDefinition beanDefinition =
BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
beanFactory.registerBeanDefinition("config", beanDefinition);
System.out.println("Step 1: Current bean definitions");
printBeanDefinitions(beanFactory);
System.out.println("Step 2: After registering annotation processors");
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
printBeanDefinitions(beanFactory);
System.out.println("Step 3: After executing BeanFactoryPostProcessor");
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class)
.values().forEach(bpp -> bpp.postProcessBeanFactory(beanFactory));
printBeanDefinitions(beanFactory);
// If you get Bean1 before BeanPostProcessor, the @Autowired dependency will not be injected.
// System.out.println(beanFactory.getBean(Bean1.class).getBean2());
System.out.println("Step 4: After executing BeanPostProcessor and pre-instantiating singletons");
beanFactory.getBeansOfType(BeanPostProcessor.class)
.values().forEach(beanFactory::addBeanPostProcessor);
beanFactory.preInstantiateSingletons();
System.out.println("=============================");
System.out.println(beanFactory.getBean(Bean1.class).getBean2());
/*
* Summary of BeanFactory characteristics:
* 1. Does not automatically invoke BeanFactory post-processors.
* 2. Does not automatically add Bean post-processors.
* 3. Does not automatically initialize singletons.
* 4. Does not resolve EL expressions.
*/
}
@Configuration
static class Config {
@Bean
public Bean1 bean1() { return new Bean1(); }
@Bean
public Bean2 bean2() { return new Bean2(); }
}
static class Bean1 {
private static final Logger log = LoggerFactory.getLogger(Bean1.class);
public Bean1() { log.debug("Constructing Bean1()"); }
@Autowired
private Bean2 bean2;
public Bean2 getBean2() { return bean2; }
}
static class Bean2 {
private static final Logger log = LoggerFactory.getLogger(Bean2.class);
public Bean2() { log.debug("Constructing Bean2()"); }
}
}
Output:
Step 1: Current bean definitions
config
Step 2: After registering annotation processors
config
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
Step 3: After executing BeanFactoryPostProcessor
[2022-05-19 20:43:30] [DEBUG] -- Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
[2022-05-19 20:43:30] [DEBUG] -- Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor'
[2022-05-19 20:43:30] [DEBUG] -- Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
config
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
bean1
bean2
Step 4: After executing BeanPostProcessor and pre-instantiating singletons
[2022-05-19 20:43:30] [DEBUG] -- Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
[2022-05-19 20:43:30] [DEBUG] -- Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
[2022-05-19 20:43:30] [DEBUG] -- Creating shared instance of singleton bean 'config'
[2022-05-19 20:43:30] [DEBUG] -- Creating shared instance of singleton bean 'bean1'
[2022-05-19 20:43:30] [DEBUG] -- Constructing Bean1()
[2022-05-19 20:43:30] [DEBUG] -- Creating shared instance of singleton bean 'bean2'
[2022-05-19 20:43:30] [DEBUG] -- Constructing Bean2()
=============================
com.village.dog.TestBeanFactory$Bean2@61862a7f
Explanation: DefaultListableBeanFactory is the implementation of the BeanFactory interface. This factory creates bean instances for external use. To do so, it must parse each bean's class too generate a BeanDefinition (a description containing property values, constructor argument values, etc.).
Clearly, "how to derive a BeanDefinition from a Bean" is crucial for BeanFactory. As long as you can correctly parse the Bean class to obtain the BeanDefinition, you can correctly create the desired bean.
In practice, we use annotations to place beans into the container. This work is done by BeanFactoryPostProcessor (which parses beans to generate BeanDefinitions) and BeanPostProcessor (which injects dependencies into bean instances).
- BeanFactoryPostProcessor: Factory hook that allows custom modification of an application context's bean definitions, adapting the bean property values of the context's underlying bean factory.
- BeanPostProcessor: Factory hook that allows custom modification of new bean instances, for example, checking for marker interfaces or wrapping beans with proxies.
Design philosophy: Using hook programs at fixed points in the program allows flexible functionality, embodying the Open/Closed Principle.
Bean Post-Processor Ordering
package com.village.dog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
public class TestBeanFactory {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
AbstractBeanDefinition beanDefinition =
BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
beanFactory.registerBeanDefinition("config", beanDefinition);
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class)
.values().forEach(bpp -> bpp.postProcessBeanFactory(beanFactory));
// Define custom ordering of BeanPostProcessors
beanFactory.getBeansOfType(BeanPostProcessor.class).values().stream()
.sorted(beanFactory.getDependencyComparator())
.forEach(beanPostProcessor -> {
System.out.println("BeanPostProcessor: " + beanPostProcessor);
beanFactory.addBeanPostProcessor(beanPostProcessor);
});
System.out.println(beanFactory.getBean(Bean1.class).getBean3());
}
@Configuration
static class Config {
@Bean
public Bean1 bean1() { return new Bean1(); }
@Bean
public Bean2 bean2() { return new Bean2(); }
@Bean
public Bean3 bean3() { return new Bean3(); }
@Bean
public Bean4 bean4() { return new Bean4(); }
}
static class Bean1 {
private static final Logger log = LoggerFactory.getLogger(Bean1.class);
public Bean1() { log.debug("Constructing Bean1()"); }
@Autowired
private Bean2 bean2;
public Bean2 getBean2() { return bean2; }
@Autowired
@Resource(name = "bean4")
Inter bean3;
public Inter getBean3() { return bean3; }
}
static class Bean2 {
private static final Logger log = LoggerFactory.getLogger(Bean2.class);
public Bean2() { log.debug("Constructing Bean2()"); }
}
interface Inter { void get(); }
static class Bean3 implements Inter {
@Override
public void get() {}
}
static class Bean4 implements Inter {
@Override
public void get() {}
}
}
2-2 ApplicationContext Interface Implementation Classes
Spring provides four common implementations of the ApplicationContext interface:
| Container Class | Description |
|---|---|
ClassPathXmlApplicationContext |
Loads configuration from an XML file on the classpath. |
FileSystemXmlApplicationContext |
Loads configuration from a XML file on the filesystem. |
AnnotationConfigApplicationContext |
Creates a container based on Java configuraton classes. |
AnnotationConfigServletWebServerApplicationContext |
Creates a container based on Java configuration classes, suitable for web environments. |
Test code for the four implementations:
package com.village.dog;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletRegistrationBean;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.mvc.Controller;
public class TestApplicationContext {
public static void main(String[] args) {
System.out.println("Testing ClassPathXmlApplicationContext");
testClassPathXmlApplicationContext();
System.out.println("Testing AnnotationConfigApplicationContext");
testAnnotationConfigApplicationContext();
System.out.println("Testing AnnotationConfigServletWebServerApplicationContext");
testAnnotationConfigServletWebServerApplicationContext();
}
private static void testClassPathXmlApplicationContext() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("b01.xml");
printBeanDefinitionNames(context);
System.out.println(context.getBean(Bean2.class).getBean1());
System.out.println();
}
private static void testAnnotationConfigApplicationContext() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
printBeanDefinitionNames(context);
System.out.println(context.getBean(Bean2.class).getBean1());
System.out.println();
}
private static void testAnnotationConfigServletWebServerApplicationContext() {
AnnotationConfigServletWebServerApplicationContext context =
new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
printBeanDefinitionNames(context);
System.out.println();
}
@Configuration
static class WebConfig {
@Bean
public ServletWebServerFactory servletWebServerFactory() {
return new TomcatServletWebServerFactory();
}
@Bean
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
@Bean
public DispatcherServletRegistrationBean registrationBean(DispatcherServlet dispatcherServlet) {
return new DispatcherServletRegistrationBean(dispatcherServlet, "/");
}
@Bean("/hello")
public Controller controller1() {
return (request, response) -> {
response.getWriter().print("Response Message:Hello");
return null;
};
}
}
@Configuration
static class Config {
@Bean
public Bean1 bean1() { return new Bean1(); }
@Bean
public Bean2 bean2(Bean1 bean1) {
Bean2 bean2 = new Bean2();
bean2.setBean1(bean1);
return bean2;
}
}
static class Bean1 {}
static class Bean2 {
private Bean1 bean1;
public void setBean1(Bean1 bean1) { this.bean1 = bean1; }
public Bean1 getBean1() { return bean1; }
}
private static void printBeanDefinitionNames(ListableBeanFactory beanFactory) {
System.out.println("==============Bean Definitions==================");
for (String name : beanFactory.getBeanDefinitionNames()) {
System.out.println(name);
}
System.out.println("===============================================");
}
}
Output: (truncated for brevity)
Testing ClassPathXmlApplicationContext
[DEBUG] -- Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5afa04c
[DEBUG] -- Loaded 2 bean definitions from class path resource [b01.xml]
[DEBUG] -- Creating shared instance of singleton bean 'bean1'
[DEBUG] -- Creating shared instance of singleton bean 'bean2'
==============Bean Definitions==================
bean1
bean2
===============================================
com.village.dog.TestApplicationContext$Bean1@475e586c
Testing AnnotationConfigApplicationContext
[DEBUG] -- Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@5c1a8622
[DEBUG] -- Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
[DEBUG] -- Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor'
[DEBUG] -- Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
[DEBUG] -- Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
[DEBUG] -- Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
[DEBUG] -- Creating shared instance of singleton bean 'testApplicationContext.Config'
[DEBUG] -- Creating shared instance of singleton bean 'bean1'
[DEBUG] -- Creating shared instance of singleton bean 'bean2'
[DEBUG] -- Autowiring by type from bean name 'bean2' via factory method to bean named 'bean1'
==============Bean Definitions==================
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
testApplicationContext.Config
bean1
bean2
===============================================
com.village.dog.TestApplicationContext$Bean1@21b2e768
Testing AnnotationConfigServletWebServerApplicationContext
[DEBUG] -- Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@11c9af63
...
==============Bean Definitions==================
...
/hello
===============================================
Summary: The four ApplicationContext implementations use two configuration approaches: XML-based and annotation-based (via @Configuration classes). The annotation-based approach parses annotations like @Autowired using built-in bean post-processors. In a web environment, the container must include at least a web container (e.g., Tomcat), a DispatcherServlet, and a registration bean for the servlet.
Key Takeaways
Question 1: What is the relationship between BeanFactory and ApplicationContext?
BeanFactoryis the core interface of the Spring container and the parent interface ofApplicationContext.ApplicationContextcomposesBeanFactoryfunctionality. More precisely,ApplicationContextimplementations have an internal member variable that is an implementation ofBeanFactory, which is used to invokeBeanFactorymethods.
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
// ...
}
Question 2: What extra features does ApplicationContext provide beyond BeanFactory?
ApplicationContext inherits additional interfaces, adding four features:
- Internationalization (via
MessageSource). - Loading resources using wildcards (via
ResourcePatternResolver). - Retrieving configuration/environment information (via
EnvironmentCapable). - Publishing events (via
ApplicationEventPublisher).
Question 3: How does ApplicationContext support event-driven decoupling?
Event-driven decoupling embodies the Observer pattern. The ApplicationEventPublisher parent interface provides this capability.
Question 4: What are the characteristics of BeanFactory implementations?
As a low-level class, BeanFactory does not:
- Automatically invoke
BeanFactoryPostProcessors. - Automatically add
BeanPostProcessors(to resolve@Autowired,@Resource). - Automatically initialize singletons.
- Resolve
${}or#{}(EL expressions).
Question 5: What are the common implementations and usage of ApplicationContext?
The four common implementations use two configuration styles: XML-based (via ClassPathXmlApplicationContext or FileSystemXmlApplicationContext) and annotation-based (via AnnotationConfigApplicationContext or its web variant).
References
- Spring 5 tutorial videos
- Introduction to circular dependencies