Spring ApplicationContext

ApplicationContext 在 Spring 中代表着一个高级的 IoC 容器,负责实例化、配置和组装对象。ApplicationContext 接口扩展自 BeanFactory 接口,添加了更多的企业级功能,比如更容易的国际化、事件传播、资源加载等。

ApplicationContext 接口关系

ApplicationContext 是一个功能丰富的接口,它继承自 ListableBeanFactoryHierarchicalBeanFactory 等多个接口,并且添加了其他特性。它的层级关系如下所示:

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
    // 各种方法
}
  • EnvironmentCapable:提供对环境属性的访问。
  • ListableBeanFactory:允许列举所有 bean 实例,而不是按名字逐个查找。
  • HierarchicalBeanFactory:允许一个 bean 工厂成为另一个 bean 工厂的子工厂。
  • MessageSource:国际化功能。
  • ApplicationEventPublisher:事件发布功能。
  • ResourcePatternResolver:资源加载功能。

实现类 ClassPathXmlApplicationContext

一个非常常见的 ApplicationContext 实现是 ClassPathXmlApplicationContext,它从类路径下的 XML 文件加载配置元数据并初始化应用上下文。我们分析一下它的关键源代码。

public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {

    private String[] configLocations;

    public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
        this(new String[] {configLocation}, true, null);
    }

    public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
            throws BeansException {
        super(parent);
        setConfigLocations(configLocations);
        if (refresh) {
            refresh(); // 初始化 ApplicationContext
        }
    }

    @Override
    protected String[] getConfigLocations() {
        return this.configLocations;
    }

    // 其他方法...
}

ClassPathXmlApplicationContext 继承自 AbstractXmlApplicationContext,在构造方法中可以指定配置文件的位置,还可以决定是否立即进行初始化(通过调用 refresh() 方法)。

refresh 方法解析

refresh() 方法在 AbstractApplicationContext 中定义,是 Spring 容器启动的核心方法。以下是简化版本的源代码:

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {

    @Override
   public void refresh() throws BeansException, IllegalStateException {
       synchronized (this.startupShutdownMonitor) {
           // Prepare this context for refreshing.
           prepareRefresh();

           // Tell the subclass to refresh the internal bean factory.
           ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

           // Prepare the bean factory for use in this context.
           prepareBeanFactory(beanFactory);

           try {
               // Allows post-processing of the bean factory in context subclasses.
               postProcessBeanFactory(beanFactory);

               // Invoke factory processors registered as beans in the context.
               invokeBeanFactoryPostProcessors(beanFactory);

               // Register bean processors that intercept bean creation.
               registerBeanPostProcessors(beanFactory);

               // Initialize message source for this context.
               initMessageSource();

               // Initialize event multicaster for this context.
               initApplicationEventMulticaster();

               // Initialize other special beans in specific context subclasses.
               onRefresh();

               // Check for listener beans and register them.
               registerListeners();

               // Instantiate all remaining (non-lazy-init) singletons.
               finishBeanFactoryInitialization(beanFactory);

               // Last step: publish corresponding event.
               finishRefresh();
           }

           // 其他异常处理代码...
       }
   }

   // 其他方法...
}

refresh() 方法调用了一系列准备和初始化的步骤:

  1. prepareRefresh():准备上下文,设置开始时间、活动标志等。
  2. obtainFreshBeanFactory():刷新内部的 BeanFactory,并获取它。
  3. prepareBeanFactory(beanFactory):设置类加载器、后置处理器等。
  4. postProcessBeanFactory(beanFactory):提供子类覆写的扩展点,用于添加额外的处理。
  5. invokeBeanFactoryPostProcessors(beanFactory):调用所有注册的 BeanFactoryPostProcessor。
  6. registerBeanPostProcessors(beanFactory):注册 BeanPostProcessor。
  7. initMessageSource():初始化消息资源处理,用于国际化。
  8. initApplicationEventMulticaster():初始化事件广播器。
  9. onRefresh():由子类覆写,用于特定上下文的 bean 初始化。
  10. registerListeners():注册监听器。
  11. finishBeanFactoryInitialization(beanFactory):初始化剩余的单例 beans。
  12. finishRefresh():最后一步,广播相关事件(比如上下文刷新事件)。

总结

ApplicationContext 通过 refresh() 方法的调用来初始化 Spring 容器。这个方法是整个应用上下文生命周期中非常重要的一部分,它会创建和初始化所有的 beans,同时处理依赖注入。

正是通过这个复杂而强大的初始化过程,Spring 能够管理应用中的 beans,并提供如 AOP、事务管理、事件发布等特性。虽然 ApplicationContext 提供了非常丰富的功能,但是作为开发者,我们通常只需要与它的几个核心方法打交道,如 getBean()register()refresh() 等,而 Spring 框架会处理其背后的复杂逻辑。