Spring源码【10】IOC容器(一)

111 阅读14分钟

1 启动入口

1.1 ApplicationContext

一般情况下,Spring的启动入口为new ClassPathXmlApplicationContext(configLocations);new FileSystemXmlApplicationContext(configLocations)

org.springframework.context.ApplicationContext的向下子类类继承关系如下:

ConfigurableApplicationContext (org.springframework.context)
    AbstractApplicationContext (org.springframework.context.support)
        GenericApplicationContext (org.springframework.context.support)
            GenericXmlApplicationContext (org.springframework.context.support)
            StaticApplicationContext (org.springframework.context.support)
            ResourceAdapterApplicationContext (org.springframework.jca.context)
            GenericGroovyApplicationContext (org.springframework.context.support)
            AnnotationConfigApplicationContext (org.springframework.context.annotation)
        AbstractRefreshableApplicationContext (org.springframework.context.support)
            AbstractRefreshableConfigApplicationContext (org.springframework.context.support)
                AbstractXmlApplicationContext (org.springframework.context.support)
                    FileSystemXmlApplicationContext (org.springframework.context.support)
                    ClassPathXmlApplicationContext (org.springframework.context.support)

向上的父类类继承关系如下:

EnvironmentCapable (org.springframework.core.env)
ListableBeanFactory (org.springframework.beans.factory)
    BeanFactory (org.springframework.beans.factory)
HierarchicalBeanFactory (org.springframework.beans.factory)
    BeanFactory (org.springframework.beans.factory)
MessageSource (org.springframework.context)
ApplicationEventPublisher (org.springframework.context)
ResourcePatternResolver (org.springframework.core.io.support)
    ResourceLoader (org.springframework.core.io)

1.1.1 ApplicationContext接口分析

通过分析类实现的接口,下面分析每个接口的职责范围。

1.1.1.1 EnvironmentCapable

org.springframework.core.env.EnvironmentCapable的实现如下:

public interface EnvironmentCapable {
    // 展示一个Component包含的组件,并将该组件暴露出来
    Environment getEnvironment();
}

1.1.1.2 BeanFactory

org.springframework.beans.factory.BeanFactory为Spring IOC的核心接口,实现从IOC查询Bean的接口,实现如下:

public interface BeanFactory {

    // 用于解引用{@link FactoryBean}实例,并将其与FactoryBean<i>创建的bean区分开来。例如,如果名为{@code myJndiObject}的bean是一个FactoryBean,则获取{@code &myJndiObject}将返回工厂,而不是工厂返回的实例。
    String FACTORY_BEAN_PREFIX = "&";

    // 根据Bean名称查询Bean对象
    Object getBean(String name) throws BeansException;

    <T> T getBean(String name, Class<T> requiredType) throws BeansException;

    // args为指定的构造Bean的参数
    Object getBean(String name, Object... args) throws BeansException;

    <T> T getBean(Class<T> requiredType) throws BeansException;

    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

    // 根据指定的类型,获取ObjectProvider,对依赖注入进行更加宽松的配置
    <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

    // org.springframework.core.ResolvableType是对Java type类型的封装
    <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

    boolean containsBean(String name);

    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

    // 是否是prototype类型,在每次注入或者通过Spring应用上下文获取的时候,都会创建一个新的bean实例
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

    @Nullable
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;

    // 如果判断的是一个FactoryBean,是否允许其触发初始化已获取FactoryBean的类型
    @Nullable
    Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;

    // 获取对应Bean的别名
    String[] getAliases(String name);

}

org.springframework.beans.factory.ObjectFactory的接口实现如下:

@FunctionalInterface // 函数式接口
public interface ObjectFactory<T> {
    T getObject() throws BeansException; // 返回一个指定类型的Bean
}

org.springframework.beans.factory.ObjectProvider的实现如下:

// 专门为注入点设计的{@link ObjectFactory}的变体,允许编程的可选性和宽松的非唯一性处理。
public interface ObjectProvider<T> extends ObjectFactory<T>, Iterable<T> {

    // 根据创建Bean时的参数获取Bean
    T getObject(Object... args) throws BeansException;

    @Nullable
    T getIfAvailable() throws BeansException;

    default T getIfAvailable(Supplier<T> defaultSupplier) throws BeansException {
       T dependency = getIfAvailable();
       return (dependency != null ? dependency : defaultSupplier.get());
    }

    // 由于是函数式接口,如果可以获取,则使用dependencyConsumer进行消费
    default void ifAvailable(Consumer<T> dependencyConsumer) throws BeansException {
       T dependency = getIfAvailable();
       if (dependency != null) {
          dependencyConsumer.accept(dependency);
       }
    }

    @Nullable
    T getIfUnique() throws BeansException;

    default T getIfUnique(Supplier<T> defaultSupplier) throws BeansException {
       T dependency = getIfUnique();
       return (dependency != null ? dependency : defaultSupplier.get());
    }

    default void ifUnique(Consumer<T> dependencyConsumer) throws BeansException {
       T dependency = getIfUnique();
       if (dependency != null) {
          dependencyConsumer.accept(dependency);
       }
    }

    @Override
    default Iterator<T> iterator() {
       return stream().iterator();
    }

    default Stream<T> stream() {
       throw new UnsupportedOperationException("Multi element access not supported");
    }

    default Stream<T> orderedStream() {
       throw new UnsupportedOperationException("Ordered element access not supported");
    }

}

1.1.1.3 ListableBeanFactory

org.springframework.beans.factory.ListableBeanFactory,用于获取IOC中的所有Bean的信息,扩展BeanFactory只能单个获取Bean的能力,实现如下:

public interface ListableBeanFactory extends BeanFactory {

    // BeanFactory中是否包含对应的beanName
    boolean containsBeanDefinition(String beanName);

    // 获取所有定义的Bean数量
    int getBeanDefinitionCount();

    // 获取所有定义的Bean的名称
    String[] getBeanDefinitionNames();

    // 根据指定的类型requiredType获取ObjectProvider,allowEagerInit是否允许触发延迟加载的Bean在此时触发加载
    <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType, boolean allowEagerInit);

    <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType, boolean allowEagerInit);

    String[] getBeanNamesForType(ResolvableType type);

    String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit);

    String[] getBeanNamesForType(@Nullable Class<?> type);

    String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);

    <T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;

    <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
          throws BeansException;
    // 获取所有使用annotationType类型注解的Bean
    String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);

    Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;

    @Nullable
    <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
          throws NoSuchBeanDefinitionException;

    @Nullable
    <A extends Annotation> A findAnnotationOnBean(
          String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
          throws NoSuchBeanDefinitionException;

}

1.1.1.4 HierarchicalBeanFactory

org.springframework.beans.factory.HierarchicalBeanFactory定义了类的层次关系,实现如下:

public interface HierarchicalBeanFactory extends BeanFactory {
    // 获取父BeanFactory
    @Nullable
    BeanFactory getParentBeanFactory();

    // 当前的BeanFactory是否包含Bean,忽略父BeanFactory
    boolean containsLocalBean(String name);

}

1.1.1.5 MessageSource

org.springframework.context.MessageSource实现国际化相关的配置读取的操作定义,定义如下:

public interface MessageSource {
    @Nullable
    String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);

    String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;

    String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;

}

1.1.1.6 ApplicationEventPublisher

org.springframework.context.ApplicationEventPublisher定义了Spring事件的操作,为函数式接口,实现如下:

@FunctionalInterface
public interface ApplicationEventPublisher {

    // 发布事件
    default void publishEvent(ApplicationEvent event) {
       publishEvent((Object) event);
    }

    void publishEvent(Object event);

}

下面分析下ApplicationEvent的实现,org.springframework.context.ApplicationEvent实现如下,其中存储了事件的来源和触发时间:

public abstract class ApplicationEvent extends EventObject {

    /** use serialVersionUID from Spring 1.2 for interoperability. */
    private static final long serialVersionUID = 7099057708183571937L;

    /** System time when the event happened. */
    private final long timestamp;

    public ApplicationEvent(Object source) {
       super(source);
       this.timestamp = System.currentTimeMillis();
    }

    public ApplicationEvent(Object source, Clock clock) {
       super(source);
       this.timestamp = clock.millis();
    }

    public final long getTimestamp() {
       return this.timestamp;
    }

}

1.1.1.7 ResourcePatternResolver

org.springframework.core.io.support.ResourcePatternResolver根据文件通配符获取配置文件地址:

public interface ResourcePatternResolver extends ResourceLoader {

    // Pseudo URL prefix for all matching resources from the class path: "classpath*:"
    // 类路径下的配置文件伪地址
    String CLASSPATH_ALL_URL_PREFIX = "classpath*:";

    // locationPattern示例xx**:**/*.xy
    Resource[] getResources(String locationPattern) throws IOException;
}

1.1.2 ConfigurableApplicationContext

ConfigurableApplicationContext实现ApplicationContext, Lifecycle, Closeable三个接口。

org.springframework.context.Lifecycle进行生命周期控制,实现如下:

public interface Lifecycle {
    // 启动当前的组件
    void start();

    // 停止当前的组件
    void stop();

    // 判断当前的组件是否在运行状态
    boolean isRunning();
}

1.2 AbstractApplicationContext

AbstractApplicationContext是ApplicationContext的实现模板,虚基类,继承org.springframework.core.io.DefaultResourceLoader接口。

1.2.1 ResourceLoader

org.springframework.core.io.ResourceLoader定义了加载配置资源的策略,实现如下:

public interface ResourceLoader {

    /** Pseudo URL prefix for loading from the class path: "classpath:". */
    String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;

    // 根据指定的路径加载配置文件
    Resource getResource(String location);

    // 暴露出加载资源文件的ClassLoader
    @Nullable
    ClassLoader getClassLoader();
}

org.springframework.core.io.DefaultResourceLoader为ResourceLoader的默认实现:

public class DefaultResourceLoader implements ResourceLoader {

    @Nullable // 加载配置资源使用的ClassLoader
    private ClassLoader classLoader;

    private final Set<ProtocolResolver> protocolResolvers = new LinkedHashSet<>(4);

    private final Map<Class<?>, Map<Resource, ?>> resourceCaches = new ConcurrentHashMap<>(4);

    public DefaultResourceLoader() {
    }

    public DefaultResourceLoader(@Nullable ClassLoader classLoader) {
       this.classLoader = classLoader;
    }

    public void setClassLoader(@Nullable ClassLoader classLoader) {
       this.classLoader = classLoader;
    }
    
    @Override
    @Nullable
    public ClassLoader getClassLoader() {
       return (this.classLoader != null ? this.classLoader : ClassUtils.getDefaultClassLoader());
    }

    // 注册ProtocolResolver
    public void addProtocolResolver(ProtocolResolver resolver) {
       Assert.notNull(resolver, "ProtocolResolver must not be null");
       this.protocolResolvers.add(resolver);
    }
    
    public Collection<ProtocolResolver> getProtocolResolvers() {
       return this.protocolResolvers;
    }

    @SuppressWarnings("unchecked")
    public <T> Map<Resource, T> getResourceCache(Class<T> valueType) {
       return (Map<Resource, T>) this.resourceCaches.computeIfAbsent(valueType, key -> new ConcurrentHashMap<>());
    }

    public void clearResourceCaches() {
       this.resourceCaches.clear();
    }

    // 解析配置文件
    @Override
    public Resource getResource(String location) {
       Assert.notNull(location, "Location must not be null");
       // 如果实现了指定的加载逻辑
       for (ProtocolResolver protocolResolver : getProtocolResolvers()) {
          Resource resource = protocolResolver.resolve(location, this);
          if (resource != null) {
             return resource;
          }
       }
       // 以/开头的资源路径示例为/org/springframework/beans/factory/support/security/callbacks.xml
       if (location.startsWith("/")) {
          return getResourceByPath(location);
       }
       // org.springframework.core.io.ClassPathResource实现了类路径加载的方式
       else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
          return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
       }
       else {
          try {
             // Try to parse the location as a URL...
             URL url = new URL(location);
             return (ResourceUtils.isFileURL(url) ? new FileUrlResource(url) : new UrlResource(url));
          }
          catch (MalformedURLException ex) {
             // No URL -> resolve as resource path.
             return getResourceByPath(location);
          }
       }
    }

    protected Resource getResourceByPath(String path) {
       return new ClassPathContextResource(path, getClassLoader());
    }

    protected static class ClassPathContextResource extends ClassPathResource implements ContextResource {

       public ClassPathContextResource(String path, @Nullable ClassLoader classLoader) {
          super(path, classLoader);
       }

       @Override
       public String getPathWithinContext() {
          return getPath();
       }

       @Override
       public Resource createRelative(String relativePath) {
          String pathToUse = StringUtils.applyRelativePath(getPath(), relativePath);
          return new ClassPathContextResource(pathToUse, getClassLoader());
       }
    }

}

org.springframework.core.io.ProtocolResolver定义每一个资源的加载逻辑:

@FunctionalInterface // 函数式接口
public interface ProtocolResolver {

    // 使用ResourceLoader获取对应location的资源
    @Nullable
    Resource resolve(String location, ResourceLoader resourceLoader);

}

1.2.2 AbstractApplicationContext实现分析

org.springframework.context.support.AbstractApplicationContext定义了IOC容器的通用实现,定义如下:

public abstract class AbstractApplicationContext extends DefaultResourceLoader
       implements ConfigurableApplicationContext {

    // Name of the MessageSource bean in the factory
    public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";

    // Name of the LifecycleProcessor bean in the factory.
    public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";

    // Name of the ApplicationEventMulticaster bean in the factory.
    public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";

    // 是否忽略Spel表达式
    private static final boolean shouldIgnoreSpel = SpringProperties.getFlag("spring.spel.ignore");
    
	static {
		// 触发ContextClosedEvent的加载
		ContextClosedEvent.class.getName();
	}

    /** Flag that indicates whether this context is currently active. */
    private final AtomicBoolean active = new AtomicBoolean();

    /** Flag that indicates whether this context has been closed already. */
    private final AtomicBoolean closed = new AtomicBoolean();

    /** Reference to the JVM shutdown hook, if registered. */
    private Thread shutdownHook;

    /** ResourcePatternResolver used by this context. */
    private ResourcePatternResolver resourcePatternResolver;

    /** LifecycleProcessor for managing the lifecycle of beans within this context. */
    private LifecycleProcessor lifecycleProcessor;

    // 用于事件发布的类
    private ApplicationEventMulticaster applicationEventMulticaster;

    // 对启动事件进行监控的类
    private ApplicationStartup applicationStartup = ApplicationStartup.DEFAULT;

    // 监听Spring事件的监听器
    private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();

    /** Local listeners registered before refresh. */
    @Nullable
    private Set<ApplicationListener<?>> earlyApplicationListeners;

    /** ApplicationEvents published before the multicaster setup. */
    @Nullable
    private Set<ApplicationEvent> earlyApplicationEvents;

    protected ConfigurableEnvironment createEnvironment() {
       return new StandardEnvironment();
    }

    // 发送Spring事件
    public void publishEvent(ApplicationEvent event) {
       publishEvent(event, null);
    }

    protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
       Assert.notNull(event, "Event must not be null");

       // Decorate event as an ApplicationEvent if necessary
       ApplicationEvent applicationEvent;
       if (event instanceof ApplicationEvent) {
          applicationEvent = (ApplicationEvent) event;
       }
       else {
          // 如果事件类型不是ApplicationEvent,则使用PayloadApplicationEvent进行发送
          applicationEvent = new PayloadApplicationEvent<>(this, event);
          if (eventType == null) {
             eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
          }
       }

       // Multicast right now if possible - or lazily once the multicaster is initialized
       if (this.earlyApplicationEvents != null) {
          this.earlyApplicationEvents.add(applicationEvent);
       }
       else {
          getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
       }

       // Publish event via parent context as well...
       if (this.parent != null) {
          if (this.parent instanceof AbstractApplicationContext) {
             ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
          }
          else {
             this.parent.publishEvent(event);
          }
       }
    }

    public void setParent(@Nullable ApplicationContext parent) {
       this.parent = parent;
       if (parent != null) {
          Environment parentEnvironment = parent.getEnvironment();
          if (parentEnvironment instanceof ConfigurableEnvironment) {
             getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
          }
       }
    }
    
    // 核心方法,刷新IOC容器,进行IOC容器的初始化,新建ApplicationContext的构造方法中,会调用refresh()
    public void refresh() throws BeansException, IllegalStateException {
       synchronized (this.startupShutdownMonitor) {
          StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

          // 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);

             StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
             // Invoke factory processors registered as beans in the context.
             invokeBeanFactoryPostProcessors(beanFactory);

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

             // 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();
          }

          catch (BeansException ex) {
             if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                      "cancelling refresh attempt: " + ex);
             }

             // Destroy already created singletons to avoid dangling resources.
             destroyBeans();

             // Reset 'active' flag.
             cancelRefresh(ex);

             // Propagate exception to caller.
             throw ex;
          }

          finally {
             // Reset common introspection caches in Spring's core, since we
             // might not ever need metadata for singleton beans anymore...
             resetCommonCaches();
             contextRefresh.end();
          }
       }
    }

    /**
     * Prepare this context for refreshing, setting its startup date and
     * active flag as well as performing any initialization of property sources.
     */
    protected void prepareRefresh() {
       // Switch to active.
       this.startupDate = System.currentTimeMillis();
       this.closed.set(false);
       this.active.set(true);

       if (logger.isDebugEnabled()) {
          if (logger.isTraceEnabled()) {
             logger.trace("Refreshing " + this);
          }
          else {
             logger.debug("Refreshing " + getDisplayName());
          }
       }

       // Initialize any placeholder property sources in the context environment.
       initPropertySources();

       // Validate that all properties marked as required are resolvable:
       // see ConfigurablePropertyResolver#setRequiredProperties
       getEnvironment().validateRequiredProperties();

       // Store pre-refresh ApplicationListeners...
       if (this.earlyApplicationListeners == null) {
          this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
       }
       else {
          // Reset local application listeners to pre-refresh state.
          this.applicationListeners.clear();
          this.applicationListeners.addAll(this.earlyApplicationListeners);
       }

       // Allow for the collection of early ApplicationEvents,
       // to be published once the multicaster is available...
       this.earlyApplicationEvents = new LinkedHashSet<>();
    }

    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
       refreshBeanFactory();
       return getBeanFactory();
    }

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
       // Tell the internal bean factory to use the context's class loader etc.
       beanFactory.setBeanClassLoader(getClassLoader());
       if (!shouldIgnoreSpel) {
          beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
       }
       beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

       // Configure the bean factory with context callbacks.
       beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
       beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
       beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
       beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
       beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
       beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
       beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
       beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);

       // BeanFactory interface not registered as resolvable type in a plain factory.
       // MessageSource registered (and found for autowiring) as a bean.
       beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
       beanFactory.registerResolvableDependency(ResourceLoader.class, this);
       beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
       beanFactory.registerResolvableDependency(ApplicationContext.class, this);

       // Register early post-processor for detecting inner beans as ApplicationListeners.
       beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

       // Detect a LoadTimeWeaver and prepare for weaving, if found.
       if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
          beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
          // Set a temporary ClassLoader for type matching.
          beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
       }

       // Register default environment beans.
       if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
          beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
       }
       if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
          beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
       }
       if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
          beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
       }
       if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
          beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
       }
    }

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
       PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

       // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
       // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
       if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null &&
             beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
          beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
          beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
       }
    }

    protected void initApplicationEventMulticaster() {
       ConfigurableListableBeanFactory beanFactory = getBeanFactory();
       if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
          this.applicationEventMulticaster =
                beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
          if (logger.isTraceEnabled()) {
             logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
          }
       }
       else {
          this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
          beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
          if (logger.isTraceEnabled()) {
             logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
                   "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
          }
       }
    }

    protected void initLifecycleProcessor() {
       ConfigurableListableBeanFactory beanFactory = getBeanFactory();
       if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
          this.lifecycleProcessor =
                beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
          if (logger.isTraceEnabled()) {
             logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
          }
       }
       else {
          DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
          defaultProcessor.setBeanFactory(beanFactory);
          this.lifecycleProcessor = defaultProcessor;
          beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
          if (logger.isTraceEnabled()) {
             logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
                   "[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
          }
       }
    }

    protected void registerListeners() {
       // Register statically specified listeners first.
       for (ApplicationListener<?> listener : getApplicationListeners()) {
          getApplicationEventMulticaster().addApplicationListener(listener);
       }

       // Do not initialize FactoryBeans here: We need to leave all regular beans
       // uninitialized to let post-processors apply to them!
       String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
       for (String listenerBeanName : listenerBeanNames) {
          getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
       }

       // Publish early application events now that we finally have a multicaster...
       Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
       this.earlyApplicationEvents = null;
       if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
          for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
             getApplicationEventMulticaster().multicastEvent(earlyEvent);
          }
       }
    }

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
       // Initialize conversion service for this context.
       if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
             beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
          beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
       }

       // Register a default embedded value resolver if no BeanFactoryPostProcessor
       // (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
       // at this point, primarily for resolution in annotation attribute values.
       if (!beanFactory.hasEmbeddedValueResolver()) {
          beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
       }

       // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
       String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
       for (String weaverAwareName : weaverAwareNames) {
          getBean(weaverAwareName);
       }

       // Stop using the temporary ClassLoader for type matching.
       beanFactory.setTempClassLoader(null);

       // Allow for caching all bean definition metadata, not expecting further changes.
       beanFactory.freezeConfiguration();

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

    @SuppressWarnings("deprecation")
    protected void finishRefresh() {
       // Clear context-level resource caches (such as ASM metadata from scanning).
       clearResourceCaches();

       // Initialize lifecycle processor for this context.
       initLifecycleProcessor();

       // Propagate refresh to lifecycle processor first.
       getLifecycleProcessor().onRefresh();

       // Publish the final event.
       publishEvent(new ContextRefreshedEvent(this));

       // Participate in LiveBeansView MBean, if active.
       if (!NativeDetector.inNativeImage()) {
          LiveBeansView.registerApplicationContext(this);
       }
    }

    protected void cancelRefresh(BeansException ex) {
       this.active.set(false);
    }

    // 设置JVM钩子函数,应用于IOC容器关闭监听
    public void registerShutdownHook() {
       if (this.shutdownHook == null) {
          // No shutdown hook registered yet.
          this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
             @Override
             public void run() {
                synchronized (startupShutdownMonitor) {
                   doClose();
                }
             }
          };
          Runtime.getRuntime().addShutdownHook(this.shutdownHook);
       }
    }

    public void close() {
       synchronized (this.startupShutdownMonitor) {
          doClose();
          // If we registered a JVM shutdown hook, we don't need it anymore now:
          // We've already explicitly closed the context.
          if (this.shutdownHook != null) {
             try {
                Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
             }
             catch (IllegalStateException ex) {
                // ignore - VM is already shutting down
             }
          }
       }
    }

    @SuppressWarnings("deprecation")
    protected void doClose() {
       // Check whether an actual close attempt is necessary...
       if (this.active.get() && this.closed.compareAndSet(false, true)) {
          if (logger.isDebugEnabled()) {
             logger.debug("Closing " + this);
          }

          if (!NativeDetector.inNativeImage()) {
             LiveBeansView.unregisterApplicationContext(this);
          }

          try {
             // Publish shutdown event.
             publishEvent(new ContextClosedEvent(this));
          }
          catch (Throwable ex) {
             logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
          }

          // Stop all Lifecycle beans, to avoid delays during individual destruction.
          if (this.lifecycleProcessor != null) {
             try {
                this.lifecycleProcessor.onClose();
             }
             catch (Throwable ex) {
                logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
             }
          }

          // Destroy all cached singletons in the context's BeanFactory.
          destroyBeans();

          // Close the state of this context itself.
          closeBeanFactory();

          // Let subclasses do some final clean-up if they wish...
          onClose();

          // Reset local application listeners to pre-refresh state.
          if (this.earlyApplicationListeners != null) {
             this.applicationListeners.clear();
             this.applicationListeners.addAll(this.earlyApplicationListeners);
          }

          // Switch to inactive.
          this.active.set(false);
       }
    }

    protected void destroyBeans() {
       getBeanFactory().destroySingletons();
    }

    @Override
    public void start() {
       getLifecycleProcessor().start();
       publishEvent(new ContextStartedEvent(this));
    }

    @Override
    public void stop() {
       getLifecycleProcessor().stop();
       publishEvent(new ContextStoppedEvent(this));
    }

    @Override
    public boolean isRunning() {
       return (this.lifecycleProcessor != null && this.lifecycleProcessor.isRunning());
    }


    //---------------------------------------------------------------------
    // Abstract methods that must be implemented by subclasses
    //---------------------------------------------------------------------
    // 子类必须实现以进行实际的配置加载
    protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;

    //Subclasses must implement this method to release their internal bean factory.
    protected abstract void closeBeanFactory();

    // Subclasses must return their internal bean factory here. They should implement the lookup efficiently, so that it can be called repeatedly without a performance penalty.
    public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
}

1.2.3 ApplicationContextEvent事件

org.springframework.context.event.ApplicationContextEvent是ApplicationEvent的实现虚类,实现如下:

public abstract class ApplicationContextEvent extends ApplicationEvent {
    // Create a new ContextStartedEvent.
    public ApplicationContextEvent(ApplicationContext source) {
       super(source);
    }

    // Get the {@code ApplicationContext} that the event was raised for.
    public final ApplicationContext getApplicationContext() {
       return (ApplicationContext) getSource();
    }
}

ApplicationContextEvent的实现类如下: ContextClosedEvent (org.springframework.context.event):IOC关闭事件 ContextRefreshedEvent (org.springframework.context.event):IOC刷新事件 ContextStoppedEvent (org.springframework.context.event):IOC停止事件

ContextStartedEvent (org.springframework.context.event):IOC启动事件

1.2.4 PathMatchingResourcePatternResolver

AbstractApplicationContext使用的ResourcePatternResolver实现为PathMatchingResourcePatternResolver,org.springframework.core.io.support.PathMatchingResourcePatternResolver实现了根据正则表达式匹配配置文件:

1.2.5 LifecycleProcessor

org.springframework.context.LifecycleProcessor实现Lifecycle接口,可以接受refresh和close事件,实现如下:

public interface LifecycleProcessor extends Lifecycle {

    // Notification of context refresh, e.g. for auto-starting components.
    void onRefresh();

    // Notification of context close phase, e.g. for auto-stopping components.
    void onClose();

}

org.springframework.context.support.DefaultLifecycleProcessor为LifecycleProcessor的默认实现类,

public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactoryAware {
    // Start all registered beans that implement {@link Lifecycle} and are not already running
    @Override
    public void start() {
       startBeans(false);
       this.running = true;
    }

    // Stop all registered beans that implement {@link Lifecycle} and are currently running.
    @Override
    public void stop() {
       stopBeans();
       this.running = false;
    }

    @Override
    public void onRefresh() {
       startBeans(true);
       this.running = true;
    }

    @Override
    public void onClose() {
       stopBeans();
       this.running = false;
    }

    @Override
    public boolean isRunning() {
       return this.running;
    }

    private void startBeans(boolean autoStartupOnly) {
       // 获取Lifecycle的实现类
       Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
       // 封装为LifecycleGroup,按照phase进行分组,phase相同的bean,一起进行启停
       Map<Integer, LifecycleGroup> phases = new TreeMap<>();

       lifecycleBeans.forEach((beanName, bean) -> {
          if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
             int phase = getPhase(bean);
             phases.computeIfAbsent(
                   phase,
                   p -> new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly)
             ).add(beanName, bean);
          }
       });
       if (!phases.isEmpty()) {
          phases.values().forEach(LifecycleGroup::start);
       }
    }

    / Start the specified bean as part of the given set of Lifecycle beans, making sure that any beans that it depends on are started first.
    private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName, boolean autoStartupOnly) {
       Lifecycle bean = lifecycleBeans.remove(beanName);
       if (bean != null && bean != this) {
          String[] dependenciesForBean = getBeanFactory().getDependenciesForBean(beanName);
          for (String dependency : dependenciesForBean) {
             doStart(lifecycleBeans, dependency, autoStartupOnly);
          }
          if (!bean.isRunning() &&
                (!autoStartupOnly || !(bean instanceof SmartLifecycle) || ((SmartLifecycle) bean).isAutoStartup())) {
             try {
                bean.start();
             }
             catch (Throwable ex) {
                throw new ApplicationContextException("Failed to start bean '" + beanName + "'", ex);
             }
          }
       }
    }

    private void stopBeans() {
       Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
       Map<Integer, LifecycleGroup> phases = new HashMap<>();
       lifecycleBeans.forEach((beanName, bean) -> {
          int shutdownPhase = getPhase(bean);
          LifecycleGroup group = phases.get(shutdownPhase);
          if (group == null) {
             group = new LifecycleGroup(shutdownPhase, this.timeoutPerShutdownPhase, lifecycleBeans, false);
             phases.put(shutdownPhase, group);
          }
          group.add(beanName, bean);
       });
       if (!phases.isEmpty()) {
          List<Integer> keys = new ArrayList<>(phases.keySet());
          keys.sort(Collections.reverseOrder());
          for (Integer key : keys) {
             phases.get(key).stop();
          }
       }
    }

    // Stop the specified bean as part of the given set of Lifecycle beans, making sure that any beans that depends on it are stopped first.
    private void doStop(Map<String, ? extends Lifecycle> lifecycleBeans, final String beanName,
          final CountDownLatch latch, final Set<String> countDownBeanNames) {

       Lifecycle bean = lifecycleBeans.remove(beanName);
       if (bean != null) {
          String[] dependentBeans = getBeanFactory().getDependentBeans(beanName);
          for (String dependentBean : dependentBeans) {
             doStop(lifecycleBeans, dependentBean, latch, countDownBeanNames);
          }
          try {
             if (bean.isRunning()) {
                if (bean instanceof SmartLifecycle) {
                   countDownBeanNames.add(beanName);
                   ((SmartLifecycle) bean).stop(() -> {
                      latch.countDown();
                      countDownBeanNames.remove(beanName);
                   });
                }
                else {
                   bean.stop();
                }
             }
             else if (bean instanceof SmartLifecycle) {
                // Don't wait for beans that aren't running...
                latch.countDown();
             }
          }
          catch (Throwable ex) {
          }
       }
    }


    // overridable hooks
    // Retrieve all applicable Lifecycle beans: all singletons that have already been created, as well as all SmartLifecycle beans (even if they are marked as lazy-init). 
    protected Map<String, Lifecycle> getLifecycleBeans() {
       ConfigurableListableBeanFactory beanFactory = getBeanFactory();
       Map<String, Lifecycle> beans = new LinkedHashMap<>();
       String[] beanNames = beanFactory.getBeanNamesForType(Lifecycle.class, false, false);
       for (String beanName : beanNames) {
          String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName);
          boolean isFactoryBean = beanFactory.isFactoryBean(beanNameToRegister);
          String beanNameToCheck = (isFactoryBean ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
          if ((beanFactory.containsSingleton(beanNameToRegister) &&
                (!isFactoryBean || matchesBeanType(Lifecycle.class, beanNameToCheck, beanFactory))) ||
                matchesBeanType(SmartLifecycle.class, beanNameToCheck, beanFactory)) {
             Object bean = beanFactory.getBean(beanNameToCheck);
             if (bean != this && bean instanceof Lifecycle) {
                beans.put(beanNameToRegister, (Lifecycle) bean);
             }
          }
       }
       return beans;
    }

    private boolean matchesBeanType(Class<?> targetType, String beanName, BeanFactory beanFactory) {
       Class<?> beanType = beanFactory.getType(beanName);
       return (beanType != null && targetType.isAssignableFrom(beanType));
    }

    protected int getPhase(Lifecycle bean) {
       return (bean instanceof Phased ? ((Phased) bean).getPhase() : 0);
    }
}

1.2.6 ApplicationStartup

org.springframework.core.metrics.ApplicationStartup的实现接口,可以接收启动过程中的启动信息。

1.2.7 ConfigurableEnvironment

org.springframework.core.env.ConfigurableEnvironment接口是Spring配置管理接口,实现如下:

public interface ConfigurableEnvironment extends Environment, ConfigurablePropertyResolver {

    // Specify the set of profiles active for this {@code Environment}. Profiles are evaluated during container bootstrap to determine whether bean definitions should be registered with the container.
    void setActiveProfiles(String... profiles);

    void addActiveProfile(String profile);

    // Specify the set of profiles to be made active by default if no other profiles are explicitly made active through {@link #setActiveProfiles}.
    void setDefaultProfiles(String... profiles);

    MutablePropertySources getPropertySources();

    // 获取系统配置属性,比如JVM的配置
    Map<String, Object> getSystemProperties();

    // 获取系统环境配置,WIN10的环境变量可以通过这种方式获取
    Map<String, Object> getSystemEnvironment();

    // Append the given parent environment's active profiles, default profiles and property sources to this (child) environment's respective collections of each.
    void merge(ConfigurableEnvironment parent);
}

org.springframework.core.env.PropertyResolver的接口实现如下:

public interface PropertyResolver {
    // 判断是否包含对应的key的配置
    boolean containsProperty(String key);

    String getProperty(String key);

    String getProperty(String key, String defaultValue);

    <T> T getProperty(String key, Class<T> targetType);

    <T> T getProperty(String key, Class<T> targetType, T defaultValue);

    String getRequiredProperty(String key) throws IllegalStateException;
    // 将value转换为对应的类型
    <T> T getRequiredProperty(String key, Class<T> targetType) throws IllegalStateException;

    // Resolve ${...} placeholders in the given text, replacing them with corresponding property values as resolved by {@link #getProperty}. Unresolvable placeholders with no default value are ignored and passed through unchanged.
    String resolvePlaceholders(String text);

    // Unresolvable placeholders with no default value will cause an IllegalArgumentException to be thrown.
    String resolveRequiredPlaceholders(String text) throws IllegalArgumentException;

}

org.springframework.core.env.ConfigurablePropertyResolver继承PropertyResolver接口,扩展配置可进行设置的能力,实现如下:

public interface ConfigurablePropertyResolver extends PropertyResolver {
    // 类型转换实现类
    ConfigurableConversionService getConversionService();

    // 设置转换实现类
    void setConversionService(ConfigurableConversionService conversionService);

    // Set the prefix that placeholders replaced by this resolver must begin with.
    void setPlaceholderPrefix(String placeholderPrefix);

    // Set the suffix that placeholders replaced by this resolver must end with.
    void setPlaceholderSuffix(String placeholderSuffix);

    // Specify the separating character between the placeholders replaced by this resolver and their associated default value, or {@code null} if no such special character should be processed as a value separator.
    void setValueSeparator(@Nullable String valueSeparator);

    // Set whether to throw an exception when encountering an unresolvable placeholder nested within the value of a given property.
    void setIgnoreUnresolvableNestedPlaceholders(boolean ignoreUnresolvableNestedPlaceholders);

    // Specify which properties must be present, to be verified by {@link #validateRequiredProperties()}.
    void setRequiredProperties(String... requiredProperties);

    // Validate that each of the properties specified by {@link #setRequiredProperties} is present and resolves to a non-{@code null} value.
    void validateRequiredProperties() throws MissingRequiredPropertiesException;
}