1,来到代码入口:
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
2,跟踪run方法:
2.1 实例化SpringApplication
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.resourceLoader = resourceLoader; //这里是null Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));//这里是DemoApplication.class, this.webApplicationType = WebApplicationType.deduceFromClasspath();//通过是否能加载相应的Class来判断应用的类型 this.bootstrappers = new ArrayList<>(getSpringFactoriesInstances(Bootstrapper.class)); //加载SpringFactories文件中的配置类 /*
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)); //加载SpringFactories文件中的类名 List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); //创建实例 AnnotationAwareOrderComparator.sort(instances);//按注解排序 return instances; }
*/ setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); //加载初始化类 setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));//加载监听器 this.mainApplicationClass = deduceMainApplicationClass();//更新main类 }
private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) { Map<String, List<String>> result = (Map)cache.get(classLoader); if (result != null) { return result; } else { HashMap result = new HashMap(); try { Enumeration urls = classLoader.getResources("META-INF/spring.factories"); while(urls.hasMoreElements()) { //jar:file:/C:/Users/Administrator/.m2/repository/org/springframework/boot/spring-boot/2.4.3/spring-boot-2.4.3.jar!/META-INF/spring.factories URL url = (URL)urls.nextElement(); UrlResource resource = new UrlResource(url); Properties properties = PropertiesLoaderUtils.loadProperties(resource); /* "org.springframework.boot.diagnostics.FailureAnalysisReporter" -> "org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter" "org.springframework.boot.diagnostics.FailureAnalyzer" -> "org.springframework.boot.context.config.ConfigDataNotFoundFailureAnalyzer,org.springframework.boot.context.properties.IncompatibleConfigurationFailureAnalyzer,org.springframework.boot.context.properties.NotConstructorBoundInjectionFailureAnalyzer,org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,org.springframework.boot.diagnostics.analyzer.BeanDefinitionOverrideFailureAnalyzer,org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,org.springframework.boot.diagnostics.analyzer.BindValidationFailureAnalyzer,org.springframework.boot.diagnostics.analyzer.UnboundConfigurationPropertyFailureAnalyzer,org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer,org.springframework.boot.diagnostics.analyzer.NoSuchMethodFailureAnalyzer,org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,org.springframework.boot.diagnostic" "org.springframework.boot.SpringBootExceptionReporter" -> "org.springframework.boot.diagnostics.FailureAnalyzers" "org.springframework.boot.SpringApplicationRunListener" -> "org.springframework.boot.context.event.EventPublishingRunListener" "org.springframework.context.ApplicationListener" -> "org.springframework.boot.ClearCachesApplicationListener,org.springframework.boot.builder.ParentContextCloserApplicationListener,org.springframework.boot.context.FileEncodingApplicationListener,org.springframework.boot.context.config.AnsiOutputApplicationListener,org.springframework.boot.context.config.DelegatingApplicationListener,org.springframework.boot.context.logging.LoggingApplicationListener,org.springframework.boot.env.EnvironmentPostProcessorApplicationListener,org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener" "org.springframework.boot.logging.LoggingSystemFactory" -> "org.springframework.boot.logging.logback.LogbackLoggingSystem.Factory,org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.Factory,org.springframework.boot.logging.java.JavaLoggingSystem.Factory" "org.springframework.boot.context.config.ConfigDataLocationResolver" -> "org.springframework.boot.context.config.ConfigTreeConfigDataLocationResolver,org.springframework.boot.context.config.StandardConfigDataLocationResolver" "org.springframework.boot.env.PropertySourceLoader" -> "org.springframework.boot.env.PropertiesPropertySourceLoader,org.springframework.boot.env.YamlPropertySourceLoader" "org.springframework.boot.context.config.ConfigDataLoader" -> "org.springframework.boot.context.config.ConfigTreeConfigDataLoader,org.springframework.boot.context.config.StandardConfigDataLoader" "org.springframework.context.ApplicationContextInitializer" -> "org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,org.springframework.boot.context.ContextIdApplicationContextInitializer,org.springframework.boot.context.config.DelegatingApplicationContextInitializer,org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer" "org.springframework.boot.env.EnvironmentPostProcessor" -> "org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor,org.springframework.boot.env.RandomValuePropertySourceEnvironmentPostProcessor,org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor,org.springframework.boot.reactor.DebugAgentEnvironmentPostProcessor" */ Iterator var6 = properties.entrySet().iterator(); while(var6.hasNext()) { Entry<?, ?> entry = (Entry)var6.next(); String factoryTypeName = ((String)entry.getKey()).trim(); String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String)entry.getValue()); String[] var10 = factoryImplementationNames; int var11 = factoryImplementationNames.length; for(int var12 = 0; var12 < var11; ++var12) { String factoryImplementationName = var10[var12]; ((List)result.computeIfAbsent(factoryTypeName, (key) -> { return new ArrayList(); })).add(factoryImplementationName.trim()); } } } result.replaceAll((factoryType, implementations) -> { return (List)implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)); }); cache.put(classLoader, result); return result; } catch (IOException var14) { throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var14); } } }
2.2 进入run方法:
public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); //记录程序开始时间 DefaultBootstrapContext bootstrapContext = createBootstrapContext();//执行Bootstrap初始化方法 ConfigurableApplicationContext context = null; configureHeadlessProperty(); SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting(bootstrapContext, this.mainApplicationClass); //启动监听类 try { ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments); //配置环境变量 configureIgnoreBeanInfo(environment); Banner printedBanner = printBanner(environment); context = createApplicationContext();//创建上下文 context.setApplicationStartup(this.applicationStartup); prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);//加载项目代码 refreshContext(context);//更新上下文 afterRefresh(context, applicationArguments); stopWatch.stop(); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch); } listeners.started(context);//运行监听器 callRunners(context, applicationArguments); } catch (Throwable ex) { handleRunFailure(context, ex, listeners); throw new IllegalStateException(ex); } try { listeners.running(context);//运行监听器 } catch (Throwable ex) { handleRunFailure(context, ex, null); throw new IllegalStateException(ex); } return context; }
全部评论