Spring boot 加载和注册 BeanDefinition (二)

上一篇只讲到主配置类的加载和注册,现在介绍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();

解释:

  1. createApplicationContext 方法的作用是创建一个 ConfigurableApplicationContext 实例,这是 Spring 的核心容器接口之一。
  2. this.applicationContextFactory.create(...) 调用了上下文工厂来实际创建上下文实例。具体创建哪种类型的上下文取决于 this.properties.getWebApplicationType() 的返回值:
    • 如果是 web 应用,创建 AnnotationConfigServletWebServerApplicationContext
    • 如果是 reactive web 应用,创建 AnnotationConfigReactiveWebServerApplicationContext
    • 默认创建 AnnotationConfigApplicationContext

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;
}

解释:

  1. create 方法负责创建应用上下文,优先使用外部配置的工厂类。
  2. createDefaultApplicationContext 是后备机制,在无自定义工厂时创建默认上下文:
    • 非 AOT 模式下使用 AnnotationConfigApplicationContext(适用于基于注解的配置)。
    • AOT 模式下使用 GenericApplicationContext(适用于提前编译场景)。
  3. 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);
	}

说明:

  • 构造函数没有 AnnotatedBeanDefinitionReaderClassPathBeanDefinitionScanner两个核心组件
  • 不支持注解驱动

📚 六、总结

AnnotationConfig开头的容器支持注解驱动,使用 AnnotatedBeanDefinitionReaderClassPathBeanDefinitionScanner两个核心组件实现注解驱动


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值