这样深度Spring Boot的源码解析,看完帮你立即提升一个台阶!

640?wx_fmt=png


实例化SpringApplication

SpringApplication.run(BootifulApplication.class, args);

 
 
public static ConfigurableApplicationContext run(Class<?> primarySource,	
   String... args) {	
return run(new Class<?>[] { primarySource }, args);	
}
 
 
public static ConfigurableApplicationContext run(Class<?>[] primarySources,	
   String[] args) {	
return new SpringApplication(primarySources).run(args);   //new SpringApplication	
}
 
 
public SpringApplication(Class<?>... primarySources) {	
this(null, primarySources);	
}
 
 
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {	
//设置资源加载器为null	
this.resourceLoader = resourceLoader;	
//断言加载资源类不能为null	
Assert.notNull(primarySources, "PrimarySources must not be null");	
//将primarySources数组转换为List,最后放到LinkedHashSet集合中	
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));	
//【1.1 推断当前应用类型是否为WEB】	
this.webApplicationType = WebApplicationType.deduceFromClasspath();	
//【1.2 设置应用上下文初始化器】	
setInitializers((Collection) getSpringFactoriesInstances(	
      ApplicationContextInitializer.class));	
//【1.3 设置监听器】	
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));	
//【1.4 推断应用的入口类】	
this.mainApplicationClass = deduceMainApplicationClass();	
}


1.1 推断当前应用类型是否为WEB

根据classpath下的内容推断出应用的类型

this.webApplicationType = WebApplicationType.deduceFromClasspath();

 
 
static WebApplicationType deduceFromClasspath() {	
   if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null)	
         && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)	
         && !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {	
      return WebApplicationType.REACTIVE;	
   }	
   for (String className : SERVLET_INDICATOR_CLASSES) {	
      if (!ClassUtils.isPresent(className, null)) {	
         return WebApplicationType.NONE;	
      }	
   }	
   return WebApplicationType.SERVLET;	
}	
	

1.2 设置应用上下文初始化器

setInitializers((Collection)getSpringFactoriesInstances(ApplicationContextInitializer.class));

  • ApplicationContextInitializer

 
 
public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {	
   /**	
    * Initialize the given application context.	
    * @param applicationContext the application to configure	
    */	
   void initialize(C applicationContext);	
}
  • getSpringFactoriesInstances(ApplicationContextInitializer.class)

 
 
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {	
   return getSpringFactoriesInstances(type, new Class<?>[] {});	
}
 
 
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,	
      Class<?>[] parameterTypes, Object... args) {	
   //获取当前上下文类加载器	
   ClassLoader classLoader = getClassLoader();	
   // Use names and ensure unique to protect against duplicates	
   //获取ApplicationContextInitializer实例名称并且去重	
   Set<String> names = new LinkedHashSet<>(	
         //进入loadFactoryNames方法并且找到loadSpringFactories---spring.factories	
         SpringFactoriesLoader.loadFactoryNames(type, classLoader));	
   //创建初始化器实例列表	
   List<T> instances = createSpringFactoriesInstances(type, parameterTypes,	
         classLoader, args, names);	
   //排序	
   AnnotationAwareOrderComparator.sort(instances);	
   return instances;	
}
  • setInitializers(...)

初始化一个ApplicationContextInitializer

 
 
public void setInitializers(	
      Collection<? extends ApplicationContextInitializer<?>> initializers) {	
   this.initializers = new ArrayList<>();	
   this.initializers.addAll(initializers);	
}	

1.3 设置监听器

setListeners((Collection)getSpringFactoriesInstances(ApplicationListener.class));

  • ApplicationListener

 
 
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {	
   /**	
    * Handle an application event.	
    * @param event the event to respond to	
    */	
   void onApplicationEvent(E event);	
}
  • getSpringFactoriesInstances(ApplicationListener.class)

 
 
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {	
   return getSpringFactoriesInstances(type, new Class<?>[] {});	
}


 
 
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,	
      Class<?>[] parameterTypes, Object... args) {	
   //获取当前上下文类加载器	
   ClassLoader classLoader = getClassLoader();	
   // Use names and ensure unique to protect against duplicates	
   //获取ApplicationContextInitializer实例名称并且去重	
   Set<String> names = new LinkedHashSet<>(	
         //进入loadFactoryNames方法并且找到loadSpringFactories---spring.factories	
         SpringFactoriesLoader.loadFactoryNames(type, classLoader));	
   List<T> instances = createSpringFactoriesInstances(type, parameterTypes,	
         classLoader, args, names);	
   //创建初始化器实例列表	
   AnnotationAwareOrderComparator.sort(instances);	
   //排序	
   return instances;	
}
  • setListeners(...)

初始化一个ApplicationListener

 
 
public void setListeners(Collection<? extends ApplicationListener<?>> listeners) {	
   this.listeners = new ArrayList<>();	
   this.listeners.addAll(listeners);	
}


1.4 推断应用的入口类

 
 
this.mainApplicationClass = deduceMainApplicationClass();
 
 
private Class<?> deduceMainApplicationClass() {	
   try {	
      //构造一个运行时异常,遍历异常栈中的方法名,获取方法名为main的栈帧,得到入口类的名字再返回该类	
      StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();	
      for (StackTraceElement stackTraceElement : stackTrace) {	
         if ("main".equals(stackTraceElement.getMethodName())) {	
            return Class.forName(stackTraceElement.getClassName());	
         }	
      }	
   }	
   catch (ClassNotFoundException ex) {	
      // Swallow and continue	
   }	
   return null;	
}

2 调用run方法

 
 
/**	
 * Run the Spring application, creating and refreshing a new	
 * {@link ApplicationContext}.	
 * @param args the application arguments (usually passed from a Java main method)	
 * @return a running {@link ApplicationContext}	
*/	
public ConfigurableApplicationContext run(String... args) {	
//创建计时类	
StopWatch stopWatch = new StopWatch();	
stopWatch.start();	
//初始化应用上下文和异常报告集合	
ConfigurableApplicationContext context = null;	
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();	
//设置headless属性	
configureHeadlessProperty();	
//【2.1 创建运行监听器】	
SpringApplicationRunListeners listeners = getRunListeners(args);	
//发布应用启动事件	
listeners.starting();	
try {	
   //初始化默认应用参数类	
   ApplicationArguments applicationArguments = new DefaultApplicationArguments(	
         args);	
   //【2.2 根据监听器和应用参数类准备Spring环境】	
   ConfigurableEnvironment environment = prepareEnvironment(listeners,	
         applicationArguments);	
   configureIgnoreBeanInfo(environment);	
   //创建Banner打印类	
   Banner printedBanner = printBanner(environment);	
   //【2.3 创建应用上下文】	
   context = createApplicationContext();	
   //准备异常报告	
   exceptionReporters = getSpringFactoriesInstances(	
         SpringBootExceptionReporter.class,	
         new Class[] { ConfigurableApplicationContext.class }, context);	
   //【2.4 准备应用上下文】	
   prepareContext(context, environment, listeners, applicationArguments,	
         printedBanner);	
   //【2.5 刷新应用上下文】	
   refreshContext(context);	
   //应用上下文后置处理刷新	
   afterRefresh(context, applicationArguments);	
   //停止计时类	
   stopWatch.stop();	
   //输出日志记录执行主类名、时间信息	
   if (this.logStartupInfo) {	
      new StartupInfoLogger(this.mainApplicationClass)	
            .logStarted(getApplicationLog(), stopWatch);	
   }	
   //发布应用上下文启动完成事件	
   listeners.started(context);	
   //【2.6 执行Runner运行器】	
   callRunners(context, applicationArguments);	
}	
catch (Throwable ex) {	
   handleRunFailure(context, ex, exceptionReporters, listeners);	
   throw new IllegalStateException(ex);	
}	
try {	
   //发布应用上下文就绪事件	
   listeners.running(context);	
}	
catch (Throwable ex) {	
   handleRunFailure(context, ex, exceptionReporters, null);	
   throw new IllegalStateException(ex);	
}	
//返回应用上下文	
return context;	
}

2.1 创建运行监听器

SpringApplicationRunListeners listeners = getRunListeners(args);

 
 
private SpringApplicationRunListeners getRunListeners(String[] args) {	
   Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };	
   return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(	
         SpringApplicationRunListener.class, types, this, args));	
}
  • SpringApplicationRunListener

org.springframework.boot:spring-boot/META-INF/spring.factories

  • getSpringFactoriesInstances(...)


 
 
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,	
      Class<?>[] parameterTypes, Object... args) {	
   ClassLoader classLoader = getClassLoader();	
   // Use names and ensure unique to protect against duplicates	
   Set<String> names = new LinkedHashSet<>(	
         SpringFactoriesLoader.loadFactoryNames(type, classLoader));	
   List<T> instances = createSpringFactoriesInstances(type, parameterTypes,	
         classLoader, args, names);	
   AnnotationAwareOrderComparator.sort(instances);	
   return instances;	
}
  • new SpringApplicationRunListeners(...)

 
 
SpringApplicationRunListeners(Log log,	
      Collection<? extends SpringApplicationRunListener> listeners) {	
   this.log = log;	
   this.listeners = new ArrayList<>(listeners);	
}

2.2 根据监听器和应用参数类准备Spring环境

ConfigurableEnvironment environment = prepareEnvironment(listeners,       applicationArguments);

 
 
private ConfigurableEnvironment prepareEnvironment(	
      SpringApplicationRunListeners listeners,	
      ApplicationArguments applicationArguments) {	
   // Create and configure the environment	
   //获取应用环境(3种情况)	
   ConfigurableEnvironment environment = getOrCreateEnvironment();	
   //配置应用环境	
   configureEnvironment(environment, applicationArguments.getSourceArgs());	
   listeners.environmentPrepared(environment);	
   bindToSpringApplication(environment);	
   if (!this.isCustomEnvironment) {	
      environment = new EnvironmentConverter(getClassLoader())	
            .convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());	
   }	
   ConfigurationPropertySources.attach(environment);	
   return environment;	
}	

2.3 创建应用上下文

context = createApplicationContext();

 
 
protected ConfigurableApplicationContext createApplicationContext() {	
   Class<?> contextClass = this.applicationContextClass;	
   if (contextClass == null) {	
      try {	
         switch (this.webApplicationType) {	
         case SERVLET:	
            contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);	
            break;	
         case REACTIVE:	
            contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);	
            break;	
         default:	
            contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);	
         }	
      }	
      catch (ClassNotFoundException ex) {	
         throw new IllegalStateException(	
               "Unable create a default ApplicationContext, "	
                     + "please specify an ApplicationContextClass",	
               ex);	
      }	
   }	
   return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);	
}


2.4 准备应用上下文

prepareContext(context, environment, listeners, applicationArguments,         printedBanner);

 
 
private void prepareContext(ConfigurableApplicationContext context,	
      ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,	
      ApplicationArguments applicationArguments, Banner printedBanner) {	
   //绑定环境到上下文	
   context.setEnvironment(environment);	
   //配置上下文的bean生成器和资源加载器	
   postProcessApplicationContext(context);	
   //为上下文采用所有初始化器	
   applyInitializers(context);	
   //触发监听器的contextPrepared事件	
   listeners.contextPrepared(context);	
   //记录启动日志	
   if (this.logStartupInfo) {	
      logStartupInfo(context.getParent() == null);	
      logStartupProfileInfo(context);	
   }	
   // Add boot specific singleton beans	
   //注册两个特殊的单例Bean	
   ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();	
   beanFactory.registerSingleton("springApplicationArguments", applicationArguments);	
   if (printedBanner != null) {	
      beanFactory.registerSingleton("springBootBanner", printedBanner);	
   }	
   if (beanFactory instanceof DefaultListableBeanFactory) {	
      ((DefaultListableBeanFactory) beanFactory)	
            .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);	
   }	
   // Load the sources	
   //加载所有资源	
   Set<Object> sources = getAllSources();	
   Assert.notEmpty(sources, "Sources must not be empty");	
   load(context, sources.toArray(new Object[0]));	
   //触发监听器的contextLoaded事件	
   listeners.contextLoaded(context);	
}


2.5 刷新应用上下文

refreshContext(context);

 
 
private void refreshContext(ConfigurableApplicationContext context) {	
   refresh(context);    //--->进入该方法	
   if (this.registerShutdownHook) {	
      try {	
         context.registerShutdownHook();	
      }	
      catch (AccessControlException ex) {	
         // Not allowed in some environments.	
      }	
   }	
}
 
 
protected void refresh(ApplicationContext applicationContext) {	
   Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);	
   ((AbstractApplicationContext) applicationContext).refresh();    //--->进入该方法	
}
 
 
public void refresh() throws BeansException, IllegalStateException {	
   synchronized (this.startupShutdownMonitor) {	
      // Prepare this context for refreshing.	
      //context:启动日期|设置context当前状态|初始化环境|验证必须	
      prepareRefresh();	
	
	
      // Tell the subclass to refresh the internal bean factory.	
      //刷新内部bean工厂,即创建一个bean工厂(对BeanDefinition的定义、解析、处理和注册)	
      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.	
         //注册WEB特性的scope(如request,session等)	
         postProcessBeanFactory(beanFactory);	
	
	
         // Invoke factory processors registered as beans in the context.	
         //调用所有的bean工厂处理器对bean进行一些处理	
         invokeBeanFactoryPostProcessors(beanFactory);	
	
	
         // Register bean processors that intercept bean creation.	
         //注册用来拦截bean	
         registerBeanPostProcessors(beanFactory);	
	
	
         // Initialize message source for this context.	
         //主要用于国际化	
         initMessageSource();	
	
	
         // Initialize event multicaster for this context.	
         //为context初始化一个事件广播器	
         initApplicationEventMulticaster();	
	
	
         // Initialize other special beans in specific context subclasses.	
         /*	
           在AbstractApplicationContext的子类中初始化其他特殊的bean。	
      其实就是初始化ThemeSource接口的实例。这个方法需要在所有单例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.	
         //调用LifecycleProcessor的onRefresh()方法并且发布事件	
         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();	
      }	
   }	
}


2.6 执行Runner运行器

callRunners(context, applicationArguments);

执行所有ApplicationRunner和CommandLineRunner两种运行器

 
 
private void callRunners(ApplicationContext context, ApplicationArguments args) {	
   List<Object> runners = new ArrayList<>();	
   runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());	
   runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());	
   AnnotationAwareOrderComparator.sort(runners);	
   for (Object runner : new LinkedHashSet<>(runners)) {	
      if (runner instanceof ApplicationRunner) {	
         callRunner((ApplicationRunner) runner, args);	
      }	
      if (runner instanceof CommandLineRunner) {	
         callRunner((CommandLineRunner) runner, args);	
      }	
   }	
}

640?wx_fmt=png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值