1、org.springframework.boot下的构造方法public SpringApplication(ResourceLoader resourceLoader, Class>... primarySources)启动,开始加载SpirngBootFactories文件,加载SpringBoot自动配置类。
-------------------------------------------------------------------------------------------
public SpringApplication(ResourceLoader resourceLoader, Class>... primarySources) {
this.sources = new linkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = new HashSet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new linkedHashSet(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = this.deduceMainApplicationClass();
}
-------------------------------------------------------------------------------------------
2、通过SpringFactoriesLoader获取spring.factories文件的set集合。
-------------------------------------------------------------------------------------------
public static List loadFactoryNames(Class> factoryType, @Nullable ClassLoader classLoader) {
String factoryTypeName = factoryType.getName();
return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}
-------------------------------------------------------------------------------------------
3、通过SpringFactoriesLoader下的loadFactories方法:获取所有meta_INFO文件下的所有配置类的List集合,通过instantiateFactory(String factoryImplementationName, Class factoryType, ClassLoader classLoader)方法获取所有配置类的Class对象,并通过反射自动创建接口实现类的对象 ,public static Constructor accessibleConstructor(Class clazz, Class>... parameterTypes),在loadFactories方法中最终返回所有的spring.factories文件的所有对象。
-------------------------------------------------------------------------------------------------------------------------------
private static T instantiateFactory(String factoryImplementationName, Class factoryType, ClassLoader classLoader) {
try {
Class> factoryImplementationClass = ClassUtils.forName(factoryImplementationName, classLoader);
if (!factoryType.isAssignableFrom(factoryImplementationClass)) {
throw new IllegalArgumentException("Class [" + factoryImplementationName + "] is not assignable to factory type [" + factoryType.getName() + "]");
} else {
return ReflectionUtils.accessibleConstructor(factoryImplementationClass, new Class[0]).newInstance();
}
} catch (Throwable var4) {
throw new IllegalArgumentException("Unable to instantiate factory class [" + factoryImplementationName + "] for factory type [" + factoryType.getName() + "]", var4);
}
}
--------------------------------------------------------------------------------------------------------------------------------
4、初始化应用容器后再初始化应用监听private Collection getSpringFactoriesInstances(Class type),把监听对象添加仅ApplicationListener容器中,初步初始化容器对象完成;
5、使用初始化容器ApplicationContext启动配置对象容器public ConfigurableApplicationContext run(String... args);开始装配@Comciguration和@Component组件对象,容器对象名称:org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@54da5fdc, started on Thu Mar 24 16:12:56 CST 2022, parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@1195d52f 容器存储了根据注解进行自动配置的对象。
6、更新ConfigurationContext容器,初始化过程中使用锁机制。
--------------------------------------------------------------------------------------------------------------------------------
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
--------------------------------------------------------------------------------------------------------------------------------
7、获取候选自动加载Bean对象进行加载。获取包扫描@ComponentScan()的结果,获取basePackage,Exclude,Fileter等结果,扫描basePackeage路径下的类,遍历basePackage路径下所有对象,如果该对象所在的下标对应的对象不在@ExcludeFilter注解之内,则把该对象加入候选人(Candidate容器内),否则给出该对象无法加入候选人容器的轨迹。
8、扫描对象加入候选人集合后,判断其候选的方式实现还是加了注解,为候选人添加操作,如果为注解候选人(@Confituration,@Component),判断所添加的注解类型赋予特性:懒加载(@Lazy)0、是否优先选择(@Primary),是否是依赖组件(@DpendsOn)(先行条件)以及角色(@Role)、描述(@Description)等
--------------------------------------------------------------------------------------------------------------------------------
while(var8.hasNext()) {
BeanDefinition candidate = (BeanDefinition)var8.next();
Scopemetadata scopemetadata = this.scopemetadataResolver.resolveScopemetadata(candidate);
candidate.setScope(scopemetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
this.postProcessBeanDefinition((AbstractBeanDefinition)candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate);
}
if (this.checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopemetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
this.registerBeanDefinition(definitionHolder, this.registry);
}
}
--------------------------------------------------------------------------------------------------------------------------------
9、根据AutoConfigurationimportFilter.class筛选出是否符合自动注入规则的对象并进行加载,loadFacotries作用看来是根据工厂类型去构建对象。
--------------------------------------------------------------------------------------------------------------------------------
protected List getAutoConfigurationimportFilters() {
return SpringFactoriesLoader.loadFactories(AutoConfigurationimportFilter.class, this.beanClassLoader);
}
--------------------------------------------------------------------------------------------------------------------------------
10、加载TemplateAvailabilityProvider模板提供程序,也是通过loadFactories(AutoConfigurationimportFilter.class, this.beanClassLoader)方法进行加载。
--------------------------------------------------------------------------------------------------------------------------------
protected List getAutoConfigurationimportFilters() {
return SpringFactoriesLoader.loadFactories(AutoConfigurationimportFilter.class, this.beanClassLoader);
}
--------------------------------------------------------------------------------------------------------------------------------
总结:以上只是粗略大致的对SpringBoot类启动流程进行梳理,也加深了自己对SpringBoot启动的理解,及源码的一些设计高深之处。