上一篇只讲到主配置类的加载和注册,现在介绍Spring boot的常见容器
。
🧩 一、创建容器详细流程
1. SpringApplication.run()
方法,核心是createApplicationContext()
方法
/**
* 运行 Spring 应用程序,创建并刷新一个新的 {@link ApplicationContext}(应用上下文)。
*
* 该方法会执行以下主要步骤:
* 1. 创建启动策略(Startup)实例;
* 2. 注册关闭钩子(如果启用);
* 3. 准备引导上下文(BootstrapContext);
* 4. 配置 headless 属性;
* 5. 获取运行监听器并通知 starting 事件;
* 6. 准备环境配置(Environment);
* 7. 打印 Banner;
* 8. 创建应用上下文;
* 9. 准备上下文环境;
* 10. 刷新上下文;
* 11. 调用 ApplicationRunner 和 CommandLineRunner;
* 12. 处理异常和失败情况;
* 13. 最后通知 listeners 应用已就绪。
*
* @param args 应用程序参数(通常由 main 方法传入)
* @return 已经运行的 {@link ConfigurableApplicationContext}
*/
public ConfigurableApplicationContext run(String... args) {
// 创建启动策略(用于处理启动指标)
Startup startup = Startup.create();
// 如果启用了注册关闭钩子,则启用它
if (this.properties.isRegisterShutdownHook()) {
SpringApplication.shutdownHook.enableShutdownHookAddition();
}
// 创建默认的 Bootstrap 上下文
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
// 初始化可配置的应用上下文为 null
ConfigurableApplicationContext context = null;
// 配置 headless 模式(默认为 true)
configureHeadlessProperty();
// 获取运行监听器并触发 starting 事件
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
// 封装应用程序参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 准备环境配置(包括系统环境、JVM 参数等)
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
// 打印 Banner(控制台或日志)
Banner printedBanner = printBanner(environment);
// 创建应用上下文(根据 WebApplicationType 决定类型)
context = createApplicationContext();
// 设置应用启动监控
context.setApplicationStartup(this.applicationStartup);
// 准备应用上下文环境(设置 BeanFactoryPostProcessors、ResourceLoader 等)
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
// 刷新上下文(加载 Bean 定义、初始化单例 Bean)
refreshContext(context);
// 刷新后处理(子类扩展点)
afterRefresh(context, applicationArguments);
// 记录启动耗时
startup.started();
// 如果启用了启动日志,记录启动完成信息
if (this.properties.isLogStartupInfo()) {
new StartupInfoLogger(this.mainApplicationClass, environment).logStarted(getApplicationLog(), startup);
}
// 通知监听器上下文已启动
listeners.started(context, startup.timeTakenToStarted());
// 调用所有 ApplicationRunner 和 CommandLineRunner
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
// 处理运行时异常
throw handleRunFailure(context, ex, listeners);
}
try {
// 如果上下文正在运行,通知监听器应用已准备就绪
if (context.isRunning()) {
listeners.ready(context, startup.ready());
}
}
catch (Throwable ex) {
// 处理就绪阶段的异常
throw handleRunFailure(context, ex, null);
}
// 返回运行中的上下文
return context;
}
2. SpringApplication.createApplicationContext()
方法
/**
* 策略方法,用于创建 {@link ApplicationContext}(应用程序上下文)。
* 默认情况下,该方法会优先使用显式设置的应用程序上下文类或工厂,
* 如果没有显式设置,则回退到合适的默认实现。
*
* @return 返回一个尚未刷新的应用程序上下文
* @see #setApplicationContextFactory(ApplicationContextFactory) 设置应用程序上下文工厂
*/
protected ConfigurableApplicationContext createApplicationContext() {
// 通过应用程序上下文工厂创建应用程序上下文
// 使用当前配置的 Web 应用类型作为参数传入
return this.applicationContextFactory.create(this.properties.getWebApplicationType());
}
this.applicationContextFactory使用的是ApplicationContextFactory.DEFAULT
,最终使用DefaultApplicationContextFactory
private ApplicationContextFactory applicationContextFactory = ApplicationContextFactory.DEFAULT;
/**
* A default {@link ApplicationContextFactory} implementation that will create an
* appropriate context for the {@link WebApplicationType}.
*/
ApplicationContextFactory DEFAULT = new DefaultApplicationContextFactory();
解释:
createApplicationContext
方法的作用是创建一个ConfigurableApplicationContext
实例,这是 Spring 的核心容器接口之一。this.applicationContextFactory.create(...)
调用了上下文工厂来实际创建上下文实例。具体创建哪种类型的上下文取决于this.properties.getWebApplicationType()
的返回值:- 如果是 web 应用,创建
AnnotationConfigServletWebServerApplicationContext
。 - 如果是 reactive web 应用,创建
AnnotationConfigReactiveWebServerApplicationContext
。 - 默认创建
AnnotationConfigApplicationContext
。
- 如果是 web 应用,创建
3. DefaultApplicationContextFactory.create()
方法
/**
* 根据给定的 WebApplicationType 创建一个 ConfigurableApplicationContext 实例。
* 首先尝试通过 SpringFactoriesLoader 加载自定义的 ApplicationContextFactory 来创建上下文,
* 如果没有找到合适的自定义工厂,则使用 createDefaultApplicationContext 方法创建默认的上下文。
*
* @param webApplicationType 应用类型(如 SERVLET、REACTIVE 或 NONE)
* @return 返回创建的可配置应用上下文
*/
public ConfigurableApplicationContext create(WebApplicationType webApplicationType) {
try {
// 尝试从 Spring 工厂加载器获取 ApplicationContextFactory 并创建上下文
return getFromSpringFactories(webApplicationType, ApplicationContextFactory::create,
this::createDefaultApplicationContext);
}
catch (Exception ex) {
// 如果创建失败,抛出非法状态异常,提示可能需要自定义的 ApplicationContextFactory
throw new IllegalStateException("无法创建默认的 ApplicationContext 实例,"
+ "您可能需要提供自定义的 ApplicationContextFactory", ex);
}
}
/**
* 创建默认的 ApplicationContext 实例。
* 如果当前不是 AOT(Ahead-Of-Time) 模式,则返回 AnnotationConfigApplicationContext。
* 否则返回 GenericApplicationContext。
*
* @return 默认的应用上下文实例
*/
private ConfigurableApplicationContext createDefaultApplicationContext() {
if (!AotDetector.useGeneratedArtifacts()) {
// 非 AOT 模式下使用基于注解的上下文
return new AnnotationConfigApplicationContext();
}
// AOT 模式下使用通用上下文
return new GenericApplicationContext();
}
/**
* 从 spring.factories 文件中加载所有可用的 ApplicationContextFactory 实现类,
* 并对每个实现类执行指定的操作(action),直到返回非空结果为止。
* 如果没有结果,则返回默认值(如果提供了的话)。
*
* @param webApplicationType 应用类型
* @param action 要执行的操作,接受 ApplicationContextFactory 和 WebApplicationType 参数,返回 T 类型的结果
* @param defaultResult 如果前面没有结果,使用的默认值提供者
* @return 返回操作的结果或默认值
*/
private <T> T getFromSpringFactories(WebApplicationType webApplicationType,
BiFunction<ApplicationContextFactory, WebApplicationType, T> action, Supplier<T> defaultResult) {
// 从 spring.factories 加载所有 ApplicationContextFactory 的实现类
for (ApplicationContextFactory candidate : SpringFactoriesLoader.loadFactories(ApplicationContextFactory.class,
getClass().getClassLoader())) {
// 对每个工厂执行 action 操作,也就是执行create方法
T result = action.apply(candidate, webApplicationType);
if (result != null) {
// 如果有结果,立即返回
return result;
}
}
// 如果没有结果且提供了默认值提供者,返回默认值
return (defaultResult != null) ? defaultResult.get() : null;
}
解释:
create
方法负责创建应用上下文,优先使用外部配置的工厂类。createDefaultApplicationContext
是后备机制,在无自定义工厂时创建默认上下文:- 非 AOT 模式下使用
AnnotationConfigApplicationContext
(适用于基于注解的配置)。 - AOT 模式下使用
GenericApplicationContext
(适用于提前编译场景)。
- 非 AOT 模式下使用
getFromSpringFactories
使用SpringFactoriesLoader
查找并调用spring.factories
中注册的ApplicationContextFactory
实现,对每个工厂实现执行create
方法。
4. META-INF/spring.factories
文件(部分)
# Application Context Factories
org.springframework.boot.ApplicationContextFactory=\
org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContextFactory,\
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContextFactory
5. ServletWebServerApplicationContextFactory.create()
方法
/**
* 根据传入的 WebApplicationType 创建对应的 ConfigurableApplicationContext 实例。
* 如果应用类型不是 SERVLET,则返回 null,表示不支持该类型。
* 如果是 SERVLET 类型,则调用 createContext() 方法创建具体的上下文实例。
*
* @param webApplicationType 应用类型(如 SERVLET、REACTIVE、NONE)
* @return 如果是 SERVLET 类型,返回对应的 ServletWebServerApplicationContext;否则返回 null
*/
@Override
public ConfigurableApplicationContext create(WebApplicationType webApplicationType) {
// 仅当应用类型为 SERVLET 时才创建对应的上下文,否则返回 null
return (webApplicationType != WebApplicationType.SERVLET) ? null : createContext();
}
/**
* 创建 SERVLET 类型的 ApplicationContext 实例。
* 根据是否处于 AOT(提前编译)模式选择不同的上下文实现:
* - 非 AOT 模式下使用 AnnotationConfigServletWebServerApplicationContext(基于注解配置)
* - AOT 模式下使用 ServletWebServerApplicationContext(适用于提前生成的场景)
*
* @return 返回创建的可配置应用上下文实例
*/
private ConfigurableApplicationContext createContext() {
if (!AotDetector.useGeneratedArtifacts()) {
// 非 AOT 模式:使用支持注解配置的 Web 服务器上下文
return new AnnotationConfigServletWebServerApplicationContext();
}
// AOT 模式:使用标准的 ServletWebServerApplicationContext
return new ServletWebServerApplicationContext();
}
6. ReactiveWebServerApplicationContextFactory.create()
方法
/**
* 根据传入的 WebApplicationType 创建对应的响应式 Web 应用上下文。
* 如果应用类型不是 REACTIVE(响应式),则返回 null,表示不支持该类型。
* 如果是 REACTIVE 类型,则调用 createContext() 方法创建具体的上下文实例。
*
* @param webApplicationType 应用类型(如 REACTIVE、SERVLET、NONE)
* @return 如果是 REACTIVE 类型,返回对应的响应式 Web 应用上下文;否则返回 null
*/
@Override
public ConfigurableApplicationContext create(WebApplicationType webApplicationType) {
// 仅当应用类型为 REACTIVE 时才创建对应的上下文,否则返回 null
return (webApplicationType != WebApplicationType.REACTIVE) ? null : createContext();
}
/**
* 创建 REACTIVE 类型的 ApplicationContext 实例。
* 根据是否处于 AOT(提前编译)模式选择不同的上下文实现:
* - 非 AOT 模式下使用 AnnotationConfigReactiveWebServerApplicationContext(基于注解配置)
* - AOT 模式下使用 ReactiveWebServerApplicationContext(适用于提前生成的场景)
*
* @return 返回创建的可配置应用上下文实例
*/
private ConfigurableApplicationContext createContext() {
if (!AotDetector.useGeneratedArtifacts()) {
// 非 AOT 模式:使用支持注解配置的响应式 Web 服务器上下文
return new AnnotationConfigReactiveWebServerApplicationContext();
}
// AOT 模式:使用标准的 ReactiveWebServerApplicationContext
return new ReactiveWebServerApplicationContext();
}
7. 为什么创建Context要区分 AOT 模式?
✅ 1. 支持 GraalVM Native Image
背景:
GraalVM Native Image 在构建阶段将 Java 字节码提前编译为机器码,生成一个独立的可执行文件(native binary),优点包括:
- 启动时间极快
- 内存占用低
- 更适合 Serverless、云原生等场景
但 Native Image 不支持某些 Java 运行时特性,如反射、动态代理、类路径加载等。
影响:
Spring Boot 原本大量依赖于反射和注解处理器来配置 Bean 和组件扫描,这些机制在 Native Image 下无法正常工作。
解决方案:
通过 AOT 模式,Spring Boot 提前生成静态代码(如 Bean 定义、配置元数据等),以替代原本需要运行时处理的部分逻辑。
所以,区分 AOT 模式是为了根据是否使用提前编译技术选择不同的上下文实现。
if (!AotDetector.useGeneratedArtifacts()) {
return new AnnotationConfigServletWebServerApplicationContext();
}
return new ServletWebServerApplicationContext();
- 非 AOT:使用基于注解的上下文(支持运行时反射)
- AOT:使用更基础的上下文(依赖预生成的配置)
✅ 2. 优化容器启动流程
在 AOT 模式下,Spring Boot 会:
- 提前分析 Bean 定义并生成代码
- 减少运行时的自动装配开销
- 禁用部分动态行为(如 CGLIB 动态代理)
这样可以大幅缩短启动时间,提高运行效率,尤其适用于冷启动频繁的场景(如函数计算、微服务边缘节点等)。
✅ 3. 兼容不同运行环境
AOT 模式并不是强制开启的,而是根据运行环境智能判断:
环境 | 是否启用 AOT |
---|---|
JVM 模式(标准 Java) | ❌ 不启用 |
GraalVM Native Image 模式 | ✅ 启用 |
通过 AotDetector.useGeneratedArtifacts()
可以检测当前是否处于 AOT 模式,从而决定使用哪种容器实现。
✅ 4. 上下文实现差异
上下文类型 | 是否支持注解驱动 | 是否适合 AOT | 说明 |
---|---|---|---|
AnnotationConfigApplicationContext | ✅ 是 | ❌ 否 | 使用注解驱动,依赖运行时反射 |
AnnotationConfigServletWebServerApplicationContext | ✅ 是 | ❌ 否 | 使用注解驱动,支持 Web 应用,依赖运行时反射 |
AnnotationConfigReactiveWebServerApplicationContext | ✅ 是 | ❌ 否 | 使用注解驱动,支持响应式 Web,依赖运行时反射 |
GenericApplicationContext | ❌ 否 | ✅ 是 | 更轻量,适合 AOT 模式下手动注册 Bean |
ServletWebServerApplicationContext | ❌ 否 | ✅ 是 | 支持 Web 应用,适合 AOT 场景 |
ReactiveWebServerApplicationContext | ❌ 否 | ✅ 是 | 支持响应式 Web,适合 AOT 场景 |
✅ 5. 总结:为什么要区分 AOT 模式?
目标 | 说明 |
---|---|
兼容 GraalVM Native Image | 替代运行时反射机制,支持提前编译 |
提升性能与效率 | 减少运行时初始化逻辑,加快启动速度 |
未来趋势 | Spring Boot 对 AOT 的全面支持是长期战略方向 |
📌 二、AnnotationConfigApplicationContext
容器,由Spring
框架提供
🔍 构造函数:
/**
* 创建一个新的 AnnotationConfigApplicationContext,
* 需要通过 {@link #register} 方法注册配置类,然后手动调用 {@linkplain #refresh} 来启动上下文。
*/
public AnnotationConfigApplicationContext() {
// 开始记录创建 AnnotatedBeanDefinitionReader 的启动步骤(用于性能监控)
StartupStep createAnnotatedBeanDefReader = getApplicationStartup().start("spring.context.annotated-bean-reader.create");
// 初始化用于读取注解定义的 Bean 读取器
this.reader = new AnnotatedBeanDefinitionReader(this);
// 结束启动步骤记录
createAnnotatedBeanDefReader.end();
// 初始化类路径下的 Bean 扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
/**
* 使用指定的 DefaultListableBeanFactory 创建一个新的 AnnotationConfigApplicationContext。
* @param beanFactory 当前上下文使用的 Bean 工厂实例
*/
public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) {
super(beanFactory); // 调用父类构造函数初始化 BeanFactory
// 初始化用于处理注解的 Bean 读取器和扫描器
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
/**
* 根据给定的组件类创建一个新的 AnnotationConfigApplicationContext,
* 并自动刷新上下文以加载 Bean 定义。
* @param componentClasses 一个或多个组件类 —— 例如:
* {@link Configuration @Configuration} 注解的类
*/
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this(); // 调用无参构造函数初始化 reader 和 scanner
register(componentClasses); // 注册传入的组件类
refresh(); // 刷新上下文,触发 Bean 的加载和初始化
}
/**
* 创建一个新的 AnnotationConfigApplicationContext,
* 扫描指定包路径下的组件类,注册 Bean 定义,并自动刷新上下文。
* @param basePackages 要扫描组件类的包路径
*/
public AnnotationConfigApplicationContext(String... basePackages) {
this(); // 调用无参构造函数初始化 reader 和 scanner
scan(basePackages); // 扫描并注册包下的组件类
refresh(); // 刷新上下文,触发 Bean 的加载和初始化
}
说明:
- 提供了多种构造函数来初始化
AnnotationConfigApplicationContext
:- 无参构造函数:需后续调用
register()
注册配置类再手动调用refresh()
。 - 带 BeanFactory 构造函数:使用自定义的
DefaultListableBeanFactory
实例化上下文。 - 带组件类构造函数:直接根据传入的组件类进行注册并自动刷新上下文。
- 带包路径构造函数:扫描指定包路径下的组件类并自动刷新上下文。
- 无参构造函数:需后续调用
- 每个构造函数都会初始化两个核心组件:
AnnotatedBeanDefinitionReader
:用于从注解类中读取并注册 Bean 定义。ClassPathBeanDefinitionScanner
:用于扫描类路径下的组件并注册 Bean。
🧱 三、AnnotationConfigServletWebServerApplicationContext
容器,由Spring boot
提供
🔍 构造函数:
/**
* 创建一个新的 {@link AnnotationConfigServletWebServerApplicationContext} 实例。
* 该上下文需要通过调用 {@link #register(Class...)} 方法注册配置类,
* 并手动调用 {@link #refresh()} 方法来完成容器的初始化。
*/
public AnnotationConfigServletWebServerApplicationContext() {
// 初始化注解 Bean 定义读取器和类路径扫描器
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
/**
* 使用指定的 DefaultListableBeanFactory 创建一个新的
* {@link AnnotationConfigServletWebServerApplicationContext} 实例。
* 上下文同样需要通过 register 注册 bean,并手动 refresh。
*
* @param beanFactory 用于此上下文的 DefaultListableBeanFactory 实例
*/
public AnnotationConfigServletWebServerApplicationContext(DefaultListableBeanFactory beanFactory) {
super(beanFactory); // 调用父类构造方法,设置自定义的 BeanFactory
// 初始化注解 Bean 定义读取器和类路径扫描器
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
/**
* 创建一个新的上下文实例,并从传入的一个或多个带注解的类(如 @Configuration)
* 中加载 Bean 定义。创建后会自动调用 refresh 方法启动容器。
*
* @param annotatedClasses 包含 Bean 定义的注解类(如 @Configuration 类)
*/
public AnnotationConfigServletWebServerApplicationContext(Class<?>... annotatedClasses) {
this(); // 先调用无参构造函数初始化 reader 和 scanner
register(annotatedClasses); // 注册传入的注解类
refresh(); // 自动刷新上下文,启动容器
}
/**
* 创建一个新的上下文实例,并扫描指定包路径下的类以发现带注解的 Bean 定义。
* 创建后会自动调用 refresh 方法启动容器。
*
* @param basePackages 需要扫描的包路径,用于查找注解类
*/
public AnnotationConfigServletWebServerApplicationContext(String... basePackages) {
this(); // 先调用无参构造函数初始化 reader 和 scanner
scan(basePackages); // 扫描包路径并注册 Bean
refresh(); // 自动刷新上下文,启动容器
}
说明:
- 每个构造函数都会初始化两个核心组件:
AnnotatedBeanDefinitionReader
:用于从注解类中读取并注册 Bean 定义。ClassPathBeanDefinitionScanner
:用于扫描类路径下的组件并注册 Bean。
🛠 四、AnnotationConfigReactiveWebServerApplicationContext
容器,由Spring boot
提供
🔍 构造函数:
/**
* 创建一个新的 {@link AnnotationConfigReactiveWebServerApplicationContext} 实例。
* 该上下文需要通过调用 {@link #register(Class...)} 方法注册配置类,
* 并手动调用 {@link #refresh()} 方法来完成容器的初始化。
*/
public AnnotationConfigReactiveWebServerApplicationContext() {
// 初始化用于处理注解类的 Bean 定义读取器和类路径扫描器
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
/**
* 使用指定的 DefaultListableBeanFactory 创建一个新的
* {@link AnnotationConfigReactiveWebServerApplicationContext} 实例。
* 上下文同样需要通过 register 注册 bean,并手动 refresh。
*
* @param beanFactory 用于此上下文的 DefaultListableBeanFactory 实例
*/
public AnnotationConfigReactiveWebServerApplicationContext(DefaultListableBeanFactory beanFactory) {
super(beanFactory); // 调用父类构造方法,设置自定义的 BeanFactory
// 初始化用于处理注解类的 Bean 定义读取器和类路径扫描器
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
/**
* 创建一个新的响应式 Web 应用上下文实例,并从传入的一个或多个带注解的类(如 @Configuration)
* 中加载 Bean 定义。创建后会自动调用 refresh 方法启动容器。
*
* @param annotatedClasses 包含 Bean 定义的注解类(如 @Configuration 类)
*/
public AnnotationConfigReactiveWebServerApplicationContext(Class<?>... annotatedClasses) {
this(); // 先调用无参构造函数初始化 reader 和 scanner
register(annotatedClasses); // 注册传入的注解类
refresh(); // 自动刷新上下文,启动容器
}
/**
* 创建一个新的响应式 Web 应用上下文实例,并扫描指定包路径下的类以发现带注解的 Bean 定义。
* 创建后会自动调用 refresh 方法启动容器。
*
* @param basePackages 需要扫描的包路径,用于查找注解类
*/
public AnnotationConfigReactiveWebServerApplicationContext(String... basePackages) {
this(); // 先调用无参构造函数初始化 reader 和 scanner
scan(basePackages); // 扫描包路径并注册 Bean
refresh(); // 自动刷新上下文,启动容器
}
说明:
- 每个构造函数都会初始化两个核心组件:
AnnotatedBeanDefinitionReader
:用于从注解类中读取并注册 Bean 定义。ClassPathBeanDefinitionScanner
:用于扫描类路径下的组件并注册 Bean。
🧪 五、GenericApplicationContext
,由Spring
框架提供
🔍 构造函数:
/**
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
/**
* Create a new GenericApplicationContext with the given DefaultListableBeanFactory.
* @param beanFactory the DefaultListableBeanFactory instance to use for this context
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext(DefaultListableBeanFactory beanFactory) {
Assert.notNull(beanFactory, "BeanFactory must not be null");
this.beanFactory = beanFactory;
}
/**
* Create a new GenericApplicationContext with the given parent.
* @param parent the parent application context
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext(@Nullable ApplicationContext parent) {
this();
setParent(parent);
}
/**
* Create a new GenericApplicationContext with the given DefaultListableBeanFactory.
* @param beanFactory the DefaultListableBeanFactory instance to use for this context
* @param parent the parent application context
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext(DefaultListableBeanFactory beanFactory, ApplicationContext parent) {
this(beanFactory);
setParent(parent);
}
说明:
- 构造函数没有
AnnotatedBeanDefinitionReader
、ClassPathBeanDefinitionScanner
两个核心组件 - 不支持注解驱动
📚 六、总结
AnnotationConfig
开头的容器支持注解驱动,使用 AnnotatedBeanDefinitionReader
、 ClassPathBeanDefinitionScanner
两个核心组件实现注解驱动