96SEO 2026-02-19 23:52 16
ingBoot启动流程分析之创建SpringApplication对象(一)

SpringBoot启动流程分析之创建SpringApplication对象(一)1、SpringApplication的构造方法1.1、推断应用程序类型1.2、设置Initializers1.3、设置Listener1.4、推断main方法所在类
来看一下在SpringApplication对象的构造方法中都做了哪些事。
SpringApplication(ResourceLoader
resourceLoader;//判断primarySources不能为空Assert.notNull(primarySources,
null);//将primarySources放入SpringApplication的全局变量primarySourcesSet集合中this.primarySources
LinkedHashSet(Arrays.asList(primarySources));//从类路径中推断应用程序类型放到SpringApplication的全局变量webApplicationType
WebApplicationType.deduceFromClasspath();//从META-INF/spring.factories文件中获取ApplicationContextInitializer接口的实现类并利用反射创建对象返回放入SpringApplication的全局变量initializersList集合中setInitializers((Collection)
getSpringFactoriesInstances(ApplicationContextInitializer.class));//同上也是从META-INF/spring.factories文件中获取ApplicationListener接口的实现类并利用反射创建对象返回放入SpringApplication的全局变量listenersList集合中setListeners((Collection)
getSpringFactoriesInstances(ApplicationListener.class));//通过获取当前调用栈找到入口方法main所在的类放入SpringApplication的全局变量mainApplicationClass
javax.servlet.Servlet,org.springframework.web.context.ConfigurableWebApplicationContext
springframework.web.reactive.DispatcherHandler;private
web.servlet.DispatcherServlet;private
org.glassfish.jersey.servlet.ServletContainer;static
{//ClassUtils.isPresent()从默认classloader中判断是否存在对应的类型if
(ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS,
!ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS,
!ClassUtils.isPresent(JERSEY_INDICATOR_CLASS,
WebApplicationType.REACTIVE;}for
(!ClassUtils.isPresent(className,
WebApplicationType.NONE;}}return
先是判断默认的classloader中是否存在org.springframework.web.reactive.DispatcherHandler、且不存在org.springframework.web.servlet.DispatcherServlet、org.glassfish.jersey.servlet.ServletContainer如果为true返回WebApplicationType.REACTIVE
然后循环String数组判断如果默认的classloader中是否不存在javax.servlet.Servlet和org.springframework.web.context.ConfigurableWebApplicationContext如果不存在则认为不是web应用程序返回WebApplicationType.NONE
最后是返回WebApplicationType.SERVLET。
1、WebApplicationType.NONE:不是web应用程序2、WebApplicationType.SERVLET:基于servlet的Web应用程序运行3、WebApplicationType.REACTIVE响应式的web应用程序1.2、设置Initializers
传入参数是class类型即ApplicationContextInitializer.class最终调用方法是getSpringFactoriesInstances注意第二个参数传的是一个空的Class数组则加载所有的配置的类方便后续给定限定类型的时候无需再次加载直接从cache中读取。
SpringFactoriesLoader.loadFactoryNames(Class?
classLoader)这个方法其作用是使用给定的类加载器从“META-INF/spring.factories”加载给定类型的工厂实现的完全限定类名即得到所有ApplicationContextInitializer接口实现类的完全限定类名去重。
getSpringFactoriesInstances(ApplicationContextInitializer.class));private
getSpringFactoriesInstances(ClassT
getSpringFactoriesInstances(type,
getSpringFactoriesInstances(ClassT
duplicates//得到所有ApplicationContextInitializer接口的实现类SetString
LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type,
classLoader));//创建所有ApplicationContextInitializer接口实现类的实例ListT
createSpringFactoriesInstances(type,
names);//根据order排序AnnotationAwareOrderComparator.sort(instances);return
}随后当做参数传递到createSpringFactoriesInstances方法中这个方法主要作用就是根据传入的type类型parameterTypes参数类型空Class数组以及得到的完全限定类名集合创建对象实例其中getDeclaredConstructor方法作用是得到指定参数类型的构造方法parameterTypes为空数组即的得到的就是默认构造方法。
构造方法基本都是空的所以无需关心创建Initializers实例的时候在构造方法中执行了什么操作。
这些对象的initialize方法会在后面的run方法中被调用。
createSpringFactoriesInstances(ClassT
classLoader);//判断是否为ApplicationContextInitializer接口的实现类Assert.isAssignable(type,
instanceClass);//得到指定参数类型的构造方法Constructor?
instanceClass.getDeclaredConstructor(parameterTypes);//创建对象T
BeanUtils.instantiateClass(constructor,
args);//放到List中返回instances.add(instance);}catch
IllegalArgumentException(Cannot
}spring.factories文件内容中Initializers如下。
这一步跟上面设置Initializers执行的操作是一样的。
spring.factories文件内容中Listener如下。
监听器事件类型BackgroundPreinitializerApplicationStartingEvent、ApplicationEnvironmentPreparedEvent、ApplicationPreparedEvent、ApplicationStartedEvent、ApplicationReadyEvent、ApplicationFailedEvent、ApplicationContextInitializedEventClearCachesApplicationListenerContextRefreshedEventParentContextCloserApplicationListenerParentContextAvailableEventFileEncodingApplicationListenerApplicationEnvironmentPreparedEventAnsiOutputApplicationListenerApplicationEnvironmentPreparedEventConfigFileApplicationListenerApplicationEnvironmentPreparedEvent、ApplicationPreparedEventDelegatingApplicationListenerApplicationEnvironmentPreparedEventClasspathLoggingApplicationListenerApplicationEnvironmentPreparedEvent、ApplicationFailedEventLoggingApplicationListenerApplicationStartingEvent、ApplicationEnvironmentPreparedEvent、ApplicationPreparedEvent、ContextClosedEvent、ApplicationFailedEventLiquibaseServiceLocatorApplicationListenerApplicationStartingEvent
StackTraceElement数组包含了StackTrace(堆栈轨迹)的内容通过遍历它可以得到当前方法以及其定义类、调用行数等信息。
{//获取StackTraceElement数组也就是这个栈的信息。
StackTraceElement[]
RuntimeException().getStackTrace();for
(main.equals(stackTraceElement.getMethodName()))
{//stackTraceElement.getClassName(),得到定义类即main方法所在类return
Class.forName(stackTraceElement.getClassName());}}}catch
SpringApplicationBuilder(RegisterApplication.class)//
设置当前应用类型.web(WebApplicationType.SERVLET)//
横幅打印方式、有关闭、日志、控制台.bannerMode(Banner.Mode.OFF)//
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback