Spring启动流程源码阅读

1、进入如下核心构造方法

public ClassPathXmlApplicationContext(
      String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
      throws BeansException {
   //调用父类构造方法,进行相关的对象创建操作,初始化一些父类成员属性
   super(parent);
   setConfigLocations(configLocations);
   if (refresh) {
      refresh();
   }
}

2、super

2.1、几层步入super(parent)

public AbstractApplicationContext(@Nullable ApplicationContext parent) {
   this();
   setParent(parent);
}

2.2、步入this()

public AbstractApplicationContext() {
   //创建资源模式处理器(解析系统允许时需要的资源)
   this.resourcePatternResolver = getResourcePatternResolver();
}

2.3、步入getResourcePatternResolver()

protected ResourcePatternResolver getResourcePatternResolver() {
   //创建一个资源模式解析器(其实就是用来解析xml配置文件)
   return new PathMatchingResourcePatternResolver(this);
}

实际上就是创建了一个PathMatchingResourcePatternResolver(this)对象。

public class PathMatchingResourcePatternResolver implements ResourcePatternResolver {

   private static final Log logger = LogFactory.getLog(PathMatchingResourcePatternResolver.class);

   @Nullable
   private static Method equinoxResolveMethod;
   private final ResourceLoader resourceLoader;
   //创建ant方式的路径匹配器
   private PathMatcher pathMatcher = new AntPathMatcher();

   ......

}

查看类图
在这里插入图片描述

只需要搞明白ResourceLoader就行,就是个资源加载器,就是加载xml文件、yml文件等资源的加载器,这些东西在加载时候都要实现这个接口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);
   
   @Nullable
   ClassLoader getClassLoader();

}

2.4、进入setParent(parent)方法

public void setParent(@Nullable ApplicationContext parent) {
   this.parent = parent;
   if (parent != null) {
      //获取父容器的环境对象
      Environment parentEnvironment = parent.getEnvironment();
      //如果当前环境对象是可配置的环境
      if (parentEnvironment instanceof ConfigurableEnvironment) {
         //进行相关的合并工作
         getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
      }
   }
}

2.5、F7往下走

public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {

    //设置xml文件的验证标志,默认true
    private boolean validating = true;

xml格式文件有一些规范要求,比如 dtd,xsd

3、步入setConfigLocations方法

setConfigLocations(configLocations);

作用是把路径设置到某个成员对象里面,方便后续能直接进行调用。

public void setConfigLocations(@Nullable String... locations) {
   if (locations != null) {
      Assert.noNullElements(locations, "Config locations must not be null");
      this.configLocations = new String[locations.length];
      for (int i = 0; i < locations.length; i++) {
          //解析给定路径,比如路径名是spring-${username}.xml时,对文件名进行解析替换
         this.configLocations[i] = resolvePath(locations[i]).trim();
      }
   }
   else {
      this.configLocations = null;
   }
}

3.1、进入resolvePath方法

protected String resolvePath(String path) {
    //将当前系统环境变量的属性值进行替换工作
   return getEnvironment().resolveRequiredPlaceholders(path);
}

里面的方法可以看懂
记住一个类名AbstractRefreshableConfigApplicationContext,里面有个属性是

//定义配置路径
 String[] configLocations;

4、refresh()核心流程

public void refresh() throws BeansException, IllegalStateException {
    //同步监视器,表示刷新和销毁的操作
   synchronized (this.startupShutdownMonitor) {
      //忽略掉,不重要,启动阶段做标记,初始化是标记位为false,执行refresh完毕后修改为true(最后的end方法)
      StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

      // Prepare this context for refreshing.
      //准备刷新上下文环境,作用就是初始化一些状态和属性,为后面的工作做准备
      //程序启动标志位、上下文拓展资源加载、上下文环境准备情况验证、监听器监听事件容器初始化准备
      //前戏,做容器刷前的准备工作
      //1、设置容器启动时间
      //2、设置活跃状态为true
      //3、设置关闭状态为false
      //4、获取Environment对象,并加载当前系统的属性值到Environment对象中
      //准备监听器和事件的集合对象,默认为空的集合
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      //初始化beanFactory 
      //加载xml配置文件的属性值到当前工厂,最重要的是BeanDefinition
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      //完成bean工厂的某些初始化操作
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         //beanfactory配置好的后置拓展操作,由子类实现,
         //可在这里提前加入自定义的beanfactorypostprocess
         postProcessBeanFactory(beanFactory);
         
         //也是启动阶段的标记操作
         StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
         // Invoke factory processors registered as beans in the context.
         //执行beanfactor后置处理,spring的spi机制报障
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         //注册beanpostprocessors到beanfactory中并排序,并未执行,涉及到bean生命周期执行
         registerBeanPostProcessors(beanFactory);
         beanPostProcess.end();

         // Initialize message source for this context.
         //初始化messagesource,用于消息国际化处理
         initMessageSource();

         // Initialize event multicaster for this context.
         //初始化上下文事件广播器
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         //子类实现,初始化特殊上下文子类的其他特殊bean,默认无实现
         onRefresh();

         // Check for listener beans and register them.
         //给广播器中注册监听器,执行初期事件
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.
         //初始化所有非懒加载的单例bean
         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.
         //销毁以及创建的单例bean,防止资源悬空
         destroyBeans();

         // Reset 'active' flag.
         //取消刷新,重装active标志位为false
         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();
         //刷新结束,设置标志位为true
         contextRefresh.end();
      }
   }
}

4.1、准备刷新上下文方法prepareRefresh()

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...
   //保留未生成context时加载的listeners监听器
   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...
   //创建applicationEvent监听事件容器
   this.earlyApplicationEvents = new LinkedHashSet<>();
}

4.2、尝试扩展一下,initPropertySources();

4.2.1、创建如下类
public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {


    /**
     * Create a new ClassPathXmlApplicationContext, loading the definitions
     * from the given XML files and automatically refreshing the context.
     *
     * @param configLocations array of resource locations
     * @throws BeansException if context creation failed
     */
    public MyClassPathXmlApplicationContext(String... configLocations) throws BeansException {
        super(configLocations);
    }

    @Override
    protected void initPropertySources() {
        System.out.println("扩展initPropertySources");
        getEnvironment().setRequiredProperties("abc");
    }
}
4.2.2、用自定义类创建容器
ApplicationContext context = new MyClassPathXmlApplicationContext("applicationContext.xml");
4.2.3、调用initPropertySources()

通过打断点的方式查看是否进入子类实现的initPropertySources()

//todo

获取beanfactory

//这俩方法均交由子类实现,大致是设置beanfactory的序列化id号,
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   refreshBeanFactory();
   return getBeanFactory();
}

初始化beanfactory各种属性和容器内容

//配置工厂的标准上下文特征,例如上下文的 ClassLoader 和后处理器。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   // Tell the internal bean factory to use the context's class loader etc.
   //设置beanfactory的类加载器
   beanFactory.setBeanClassLoader(getClassLoader());
   //判断是否需要加载spring-spel表达式解析,默认加载
   if (!shouldIgnoreSpel) {
      beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
   }
   //添加属性编辑器用于自定义属性设置覆盖
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   // Configure the bean factory with context callbacks.
   //添加默认注册bean前加入beanpostprocessor用于bean初始化前的操作
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
   //忽略一些系统级接口依赖,这些方法在上面的processor中检查回调中执行
   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.
   //设置注册不能自动创建的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.
   //添加bean初始化后操作,如果有该单例监听器bean,就加入到上下文监听器容器中
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

   // Detect a LoadTimeWeaver and prepare for weaving, if found.
   //加入AspectJ支持
   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.
   //检查并加入一些默认的初始化环境bean
   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());
   }
}

SpEL的支持
SpEL使用#{…}作为界定符,所有在大括号中的字符都可认为是spel

invokeBeanFactoryPostProcessors():激活beanfactory的后置处理器
beanFactory作为spring中容器功能的基础,用于存放已经加载的bean,为了保证程序的可扩展性,spring对beanfactory做了很多扩展,比如这个后置处理器。
这一步的功能主要时激活各种beanFactoryPostProcessors()

registerBeanPostProcessors:注册各种beanpostprocessor

initMessageSource:初始化各种消息资源。
提取配置中定义的各种messagesource,并将其记录在spring容器中,也就是abstractApplicationContext中。如果用户没有设置资源属性文件,spring提供了默认的配置delegatingMessageSource。

protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
//获取自定义资源文件。这里使用了硬编码,默认资源文件为MessageSource,否则获取不到
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
//
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace(“Using MessageSource [” + this.messageSource + “]”);
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
//如果用户没有定义就使用默认的资源文件
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace(“No '” + MESSAGE_SOURCE_BEAN_NAME + “’ bean, using [” + this.messageSource + “]”);
}
}
}

initAplicationEventMulticaster:初始化事件监听
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 {
//否则使用默认的事件广播器SimpleApplicationEventMulticaster
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() + “]”);
}
}
}
SimpleApplicationEventMulticaster里面有一段代码,如下:

public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
当spring事件产生的时候,默认使用multicastEvent方法来广播事件,遍历所有的监听器,并使用监听器中的onapplicationevent方法来进行监听事件的处理(通过invokelistener()方法激活监听方法)。而对于每个监听器来说,其实都可以获取到产生的事件。

onfresh()

registerlistener():注册监听器
分为如下三步:
一、注册硬编码注册的监听器
二、注册配置注册的监听器
三、发布之前的监听事件
代码如下:

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 earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
finishbeanfactoryinitialization:beanfactory的收尾工作
目的:结束beanfactory的初始化工作,初始化所有剩余的单例bean

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
//对conversionservice进行设置,
//如果beanfactory加载了beanname为conversionservice的bean并且类型为conversionservice,
//则设置为beanfactory的conversionservice
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.
//冻结所有bean的定义,说明注册的bean定义将不再被修改或任何进一步处理
beanFactory.freezeConfiguration();

// Instantiate all remaining (non-lazy-init) singletons.
//初始化所有剩余的非懒加载单例bean
beanFactory.preInstantiateSingletons();
}
finishRefresh()完成刷新

protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
//清除资源缓存
clearResourceCaches();

// Initialize lifecycle processor for this context.
//应用启动或停止时,通过lifestyleprocessor来与所有声明的bean周期做状态更新
//而在lifecycleprocessor的使用前首先需要初始化,这里进行初始化
initLifecycleProcessor();

// Propagate refresh to lifecycle processor first.
//启动所有实现lifecycleprocessor接口的bean
getLifecycleProcessor().onRefresh();

// Publish the final event.
//当完成applicationcontext初始化后,通过spring中的事件发布机制来发出ContextRefreshedEvent中的事件,
//以保证对应的事件监听器可以做进一步的逻辑处理
publishEvent(new ContextRefreshedEvent(this));

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汉东哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值