//复合注解,内部包含了组件扫描以及自动配置 @SpringBootApplication public class DemoApplication { public static void main(String[] args) { //引导启动应用 SpringApplication.run(DemoApplication.class, args); } }
public static ConfigurableApplicationContext run(Class[]primarySources,String[]args){ //首先new了一个SpringApplication,并且把当前启动类作为入参 return new SpringApplication(primarySources).run(args); }
public SpringApplication(ResourceLoader resourceLoader,Class...primarySources){ this.resourceLoader=resourceLoader; //引导类不能为空 Assert.notNull(primarySources,"PrimarySources must not be null"); this.primarySources=new LinkedHashSet<>(Arrays.asList(primarySources)); //获取当前应用的类型,分为三种NONE,SERVLET,REACTIVE; this.webApplicationType=WebApplicationType.deduceFromClasspath(); //设置了Spring应用上下文初始化的实例 // 获取spring.factories中前缀为org.springframework.context.ApplicationContextInitializer的集合 //并且将ApplicationContextInitializer应用于Spring ApplicationContext setInitializers((Collection)getSpringFactoriesInstances(ApplicationContextInitializer.class)); //设置了Spring上下文所需要的侦听者 //获取spring.factories中前缀为org.springframework.context.ApplicationListener的集合 setListeners((Collection)getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass=deduceMainApplicationClass(); }
static WebApplicationType deduceFromClasspath(){ //根据应用下是否存在某个特定的类来确定确定应用类型 if(ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS,null)&&!ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS,null) &&!ClassUtils.isPresent(JERSEY_INDICATOR_CLASS,null)){ //响应式web容器 return WebApplicationType.REACTIVE; } for(String className:SERVLET_INDICATOR_CLASSES){ if(!ClassUtils.isPresent(className,null)){ //非web容器 return WebApplicationType.NONE; } } //servletWeb容器 return WebApplicationType.SERVLET; }
privateCollectiongetSpringFactoriesInstances(Classtype,Class[]parameterTypes,Object...args){ ClassLoader classLoader=getClassLoader(); //根据条件加载spring.factories的实现类,并进行Set集合去重(条件:ApplicationContextInitializer) Setnames=new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type,classLoader)); //通过反射创建符合ApplicationContextInitializer接口的对应实例 Listinstances=createSpringFactoriesInstances(type,parameterTypes,classLoader,args,names); //实例集合排序(留个疑惑) AnnotationAwareOrderComparator.sort(instances); return instances; }
public static ListloadFactoryNames(Class factoryType,@Nullable ClassLoader classLoader){ //获取传入参数的转化为全限定类名,用作筛选map集合的value String factoryTypeName=factoryType.getName(); //loadSpringFactories(classLoader)加载内路径下的META-INF/spring.factories并转化为Map //map集合的getOrDefault方法用key进行对比,如果存在key则返回对应的value,否则返回默认值 return loadSpringFactories(classLoader).getOrDefault(factoryTypeName,Collections.emptyList()); }
private static Map<String, List>loadSpringFactories(@Nullable ClassLoader classLoader){ //从缓存获取当前classLoader的map集合 MultiValueMapresult=cache.get(classLoader); //如果存在,则使用当前classLoader的map集合 if(result!=null){ return result; } //否则,加载META-INF/spring.factories下的元素,并转化为map try{ // 判断当前classLoader是否为空,如果不为空,则使用当前classLoader获取绝对路径信息,否则使用系统classLoader获取信息 Enumerationurls=(classLoader!=null? classLoader.getResources(FACTORIES_RESOURCE_LOCATION): ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION)); result=new LinkedMultiValueMap<>(); while(urls.hasMoreElements()){ URL url=urls.nextElement(); UrlResource resource=new UrlResource(url); //将对应url的键值对信息转为properties格式 Properties properties=PropertiesLoaderUtils.loadProperties(resource); //遍历properties的key for(Map.Entry entry:properties.entrySet()){ String factoryTypeName=((String)entry.getKey()).trim(); //遍历对应key的value,并进行格式转化 for(String factoryImplementationName:StringUtils.commaDelimitedListToStringArray((String)entry.getValue())){ //转入对应map result.add(factoryTypeName,factoryImplementationName.trim()); } } } //map存储配置信息,方便下次取用 cache.put(classLoader,result); return result; } catch(IOException ex){ throw new IllegalArgumentException("Unable to load factories from location ["+ FACTORIES_RESOURCE_LOCATION+"]",ex); } }
# Initializers org.springframework.context.ApplicationContextInitializer=\ org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\ org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener # Application Listeners org.springframework.context.ApplicationListener=\ org.springframework.boot.autoconfigure.BackgroundPreinitializer # Auto Configuration Import Listeners org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\ org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener # Auto Configuration Import Filters org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\ org.springframework.boot.autoconfigure.condition.OnBeanCondition,\ org.springframework.boot.autoconfigure.condition.OnClassCondition,\ org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ # Failure analyzers org.springframework.boot.diagnostics.FailureAnalyzer=\ # Template availability providers org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
privateListcreateSpringFactoriesInstances(Classtype,Class[]parameterTypes, ClassLoader classLoader,Object[]args,Setnames){ Listinstances=new ArrayList<>(names.size()); //遍历前面加载的全限定类集合 for(String name:names){ try{ Class instanceClass=ClassUtils.forName(name,classLoader); Assert.isAssignable(type,instanceClass); //通过反射构造特定对象,parameterTypes为参数 Constructor constructor=instanceClass.getDeclaredConstructor(parameterTypes); T instance=(T)BeanUtils.instantiateClass(constructor,args); instances.add(instance); } catch(Throwable ex){ throw new IllegalArgumentException("Cannot instantiate "+type+" : "+name,ex); } } //将构造的对象返回 return instances; }
PS:前面讲了new SpringApplication,而入口函数就是由new SpringApplication以及run()组成的,下面将来讲一下run()的逻辑️
Copyright © 2023 leiyu.cn. All Rights Reserved. 磊宇云计算 版权所有 许可证编号:B1-20233142/B2-20230630 山东磊宇云计算有限公司 鲁ICP备2020045424号
磊宇云计算致力于以最 “绿色节能” 的方式,让每一位上云的客户成为全球绿色节能和降低碳排放的贡献者