下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、前言在spring boot 源码2 SpringApplication初始化 中我们分析SpringApplication的初始化 接下来我们继续分析SpringApplication的run方法1 SpringApplication#run方法的代码如下:该方法做13件事:初始化StopWatch 调用其start方法开始计时1调用configureHeadlessProperty设置系统属性java awt headless,这设置为true,表示运在服务端,在没有显示和鼠标键盘的模式,模拟输入输出功能2调用SpringApplicationRunListeners#starting3创
2、建一个DefaultApplicationArguments对象 它持有着args参数,就是main函数传进来的参数 调用prepareEnvironment方法4打印banner5创建SpringBoot上下文6初始化FailureAnalyzers7调用prepareContext8调用AbstractApplicationContext#refresh方法 并钩子9在容完成刷新后,依次调用的Runners10调用SpringApplicationRunListeners#finished11停止计时12初始化过程中出现异常时调用handleRunFailure进处 然后抛出 llegal
3、StateException异常13public ConfigurableApplicationContext run(String. args) / 计时工具StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; FailureAnalyzers analyzers = null; configureHeadlessProperty();SpringApplicationRunListeners listeners = getRunList
4、eners(args); listeners.starting();try / 创建一个DefaultApplicationArguments对象,它持有着args参数,就是main函数传进来的参数ApplicationArguments applicationArguments = new DefaultApplicationArguments( args);ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);Banner printedBanner = print
5、Banner(environment);/ 创建SpringBoot上下文context = createApplicationContext(); analyzers = new FailureAnalyzers(context);prepareContext(context, environment, listeners, applicationArguments, printedBanner);refreshContext(context); afterRefresh(context, applicationArguments); listeners.finished(context,
6、null); stopWatch.stop();if (this.logStartupInfo) new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);return context;catch (Throwable ex) handleRunFailure(context, listeners, analyzers, ex); throw new IllegalStateException(ex);run方法中第1步 代码如下:2在StopWatch初始化时 设置i
7、d为"" 代码如下:start方法代码如下:在start方法中 首先当前状态是否为running 如果是的话 抛出异常 如果是的话 将running设置为true currentTaskName设置为"" startTimeMillis为当前时间在run方法中的第12步中 调用StopWatch#stop方法 停止计码如下:还是同样的套 如果running为false > 抛出异常 如果是 则计算得出lastTime 初始化Task nfo 将Task nfo加入到taskList中 增加taskCount计数 将running设为false 将c
8、urrentTaskName置为nullrun方法第2步 > 调用configureHeadlessProperty方法 设置系统属性java awt headless,这设置为true,表示运在服务端,在没有显示和鼠标键盘的模式,模拟3输入输出功能 该方法如下:run方法第3步 代码如下:4getRunListeners方法如下:还是同样的味道 通过调用getSpringFactories nstances加载SpringApplicationRunListener 然后初始化SpringApplicationRunListenersprivate SpringApplicationR
9、unListeners getRunListeners(String args) Class<?> types = new Class<?> SpringApplication.class, String.class ; return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args);SpringApplicationRunListeners listeners = get
10、RunListeners(args); listeners.starting();private void configureHeadlessProperty() System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, System.getProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless);public void stop() throws IllegalStateException if (!this.running) throw new I
11、llegalStateException("Can't stop StopWatch: it's not running");long lastTime = System.currentTimeMillis() - this.startTimeMillis; this.totalTimeMillis += lastTime;this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime); if (this.keepTaskList) this.taskList.add(lastTaskInfo
12、);+this.taskCount; this.running = false; this.currentTaskName = null;public void start() throws IllegalStateException start("");public void start(String taskName) throws IllegalStateException if (this.running) throw new IllegalStateException("Can't start StopWatch: it's alread
13、y running");this.running = true; this.currentTaskName = taskName;this.startTimeMillis = System.currentTimeMillis();public StopWatch() this("");public StopWatch(String id) this.id = id;StopWatch stopWatch = new StopWatch(); stopWatch.start();对应当前场景来说 org springframework boot SpringAppl
14、icationRunListener只有一个(配置在META NF/spring factories中) 如下:在初始化EventPublishingRunListener时 会将SpringApplication中的Listeners添加到EventPublishingRunListener中的initialMulticaster 代码如下:也就是在META-INF/spring.factories中配置的org.springframework.context.ApplicationListener.关于这点,我们在上节课中讲过.然后调用SpringApplicationRunListene
15、rs#starting方法 代码如下:由于只有一个 因此会调用EventPublishingRunListener的starting方法 代码如下:接着调用SimpleApplicationEventMulticaster#multicastEvent 代码如下:resolveDefaultEventType方法如下:调用:由于当前传入的ApplicationStartedEvent是ResolvableTypeProvider的实 因此最终会调用ResolvableType#forClass 代码如下:直接初始化ResolvableType 其构造如下:public static Resol
16、vableType forClass(Class<?> clazz) return new ResolvableType(clazz);public static ResolvableType forInstance(Object instance) Assert.notNull(instance, "Instance must not be null"); if (instance instanceof ResolvableTypeProvider) ResolvableType type = (ResolvableTypeProvider) instance
17、).getResolvableType(); if (type != null) return type;return ResolvableType.forClass(instance.getClass();private ResolvableType resolveDefaultEventType(ApplicationEvent event) return ResolvableType.forInstance(event);public void multicastEvent(ApplicationEvent event) multicastEvent(event, resolveDefa
18、ultEventType(event);public void starting() this.initialMulticaster.multicastEvent(new ApplicationStartedEvent(this.application, this.args);public void starting() for (SpringApplicationRunListener listener : this.listeners) listener.starting();public EventPublishingRunListener(SpringApplication appli
19、cation, String args) this.application = application;this.args = args;this.initialMulticaster = new SimpleApplicationEventMulticaster(); for (ApplicationListener<?> listener : application.getListeners() this.initialMulticaster.addApplicationListener(listener);org.springframework.boot.SpringAppl
20、icationRunListener= org.springframework.boot.context.event.EventPublishingRunListener实现回到SimpleApplicationEventMulticaster#multicastEvent中 此时会调用该方法调用getApplicationListeners获得ApplicationListener 然后调用SimpleApplicationEventMulticaster#invokeListener方法getApplicationListeners代码如下:该方法首先构建ListenerCacheKey
21、然后缓存中是否有的话 直接返回 否则调用retrieveApplicationListeners方法 如果this beanClassLoader = null | (ClassUtils isCacheSafe(event getClass() this beanClassLoader) && (sourceType = null | ClassUtils isCacheSafe(sourceTypethis beanClassLoader) 为真的话 则调用retrieveApplicationListeners方法时会进加锁 并将方法的返回值加入缓存 一般都会放入缓存的r
22、etrieveApplicationListeners方法 代码如下:protected Collection<ApplicationListener<?>> getApplicationListeners( ApplicationEvent event, ResolvableType eventType) Object source = event.getSource();Class<?> sourceType = (source != null ? source.getClass() : null);/ 1. 构造ListenerCacheKeyList
23、enerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);/ Quick check for existing entry on ConcurrentHashMap./ 2. 如果retrieverCache中有的话,直接返回ListenerRetriever retriever = this.retrieverCache.get(cacheKey); if (retriever != null) return retriever.getApplicationListeners();if (this.beanClas
24、sLoader = null | (ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&(sourceType = null | ClassUtils.isCacheSafe(sourceType, this.beanClassLoader) / Fully synchronized building and caching of a ListenerRetriever synchronized (this.retrievalMutex) retriever = this.retrieverCache
25、.get(cacheKey); if (retriever != null) return retriever.getApplicationListeners();retriever = new ListenerRetriever(true); Collection<ApplicationListener<?>> listeners =retrieveApplicationListeners(eventType, sourceType, retriever); this.retrieverCache.put(cacheKey, retriever);return lis
26、teners;else / No ListenerRetriever caching -> no synchronization necessary return retrieveApplicationListeners(eventType, sourceType, null);public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) ResolvableType type = (eventType != null ? eventType : resolveDefaultEvent
27、Type(event); for (final ApplicationListener<?> listener : getApplicationListeners(event, type) Executor executor = getTaskExecutor(); if (executor != null) executor.execute(new Runnable() Overridepublic void run() invokeListener(listener, event););else invokeListener(listener, event);private R
28、esolvableType(Class<?> clazz) this.resolved = (clazz != null ? clazz : Object.class); / ApplicationStartedEvent.class this.type = this.resolved; / ApplicationStartedEvent.classthis.typeProvider = null; this.variableResolver = null; ponentType = null; this.hash = null;处逻辑如下:1 初始化allListeners li
29、steners listenerBeans 对于当前场景来说 listeners 中的元素如下:listenerBeans中的元素为空2 遍历listeners listenerBeans 如果是否支持指定的则加入到allListeners3 排序对于当前场景ApplicationStartedEvent支持的listeners如下:SimpleApplicationEventMulticaster#invokeListener方法如下:org.springframework.boot.logging.LoggingApplicationListener, org.springframewor
30、k.boot.autoconfigure.BackgroundPreinitializer, org.springframework.boot.context.config.DelegatingApplicationListener, org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListenerorg.springframework.boot.context.config.ConfigFileApplicationListener, org.springframework.boot.context.c
31、onfig.AnsiOutputApplicationListener, org.springframework.boot.logging.LoggingApplicationListener, org.springframework.boot.logging.ClasspathLoggingApplicationListener, org.springframework.boot.autoconfigure.BackgroundPreinitializer, org.springframework.boot.context.config.DelegatingApplicationListen
32、er, org.springframework.boot.builder.ParentContextCloserApplicationListener, org.springframework.boot.ClearCachesApplicationListener, org.springframework.boot.context.FileEncodingApplicationListener, org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListenerprivate Collection<A
33、pplicationListener<?>> retrieveApplicationListeners( ResolvableType eventType, Class<?> sourceType, ListenerRetriever retriever) LinkedList<ApplicationListener<?>> allListeners = new LinkedList<ApplicationListener<?>>(); Set<ApplicationListener<?>>
34、listeners;Set<String> listenerBeans; synchronized (this.retrievalMutex) listeners = new LinkedHashSet<ApplicationListener<?>>(this.defaultRetriever.applicationListeners); listenerBeans = new LinkedHashSet<String>(this.defaultRetriever.applicationListenerBeans);for (Applicatio
35、nListener<?> listener : listeners) if (supportsEvent(listener, eventType, sourceType) if (retriever != null) retriever.applicationListeners.add(listener);allListeners.add(listener);if (!listenerBeans.isEmpty() BeanFactory beanFactory = getBeanFactory(); for (String listenerBeanName : listenerB
36、eans) try Class<?> listenerType = beanFactory.getType(listenerBeanName);if (listenerType = null | supportsEvent(listenerType, eventType) ApplicationListener<?> listener =beanFactory.getBean(listenerBeanName, ApplicationListener.class);if (!allListeners.contains(listener) && suppo
37、rtsEvent(listener, eventType, sourceType) if (retriever != null) retriever.applicationListenerBeans.add(listenerBeanName);allListeners.add(listener);catch (NoSuchBeanDefinitionException ex) / Singleton listener instance (without backing bean definition) disappeared -/ probably in the middle of the d
38、estruction phaseAnnotationAwareOrderComparator.sort(allListeners); return allListeners;该方法主要调用do nvokeListener 当ErrorHandler为null时 当调用do nvokeListener出现异常时 会交由ErrorHandler进处 对于当前 ErrorHandler为null 那么ErrorHandler么时候进设置呢?如下:do nvokeListener代码如下:private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) try listener.onApplicationEvent(event);catch (ClassCastException ex) St
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 银行融资租赁方案范本
- 园区维护加盟方案范本
- 提高苗木成活措施方案范本
- 旋转门闸施工方案设计
- 工厂班组改造方案范本
- 村民受灾处理方案范本
- 北流施工方案
- 河堤护坡安装方案范本
- 2026届高三英语二轮复习课件:第3部分 语言运用精准篇 专题2 语法填空 考法1 有提示词类 第1讲 提示词为动词
- 子宫内膜异位症诊疗流程
- 贵州省六盘水市2025-2026学年九年级上学期期末语文试题(含答案)
- 一年级数学5以内加减法计算专项练习题(每日一练共42份)
- 2026年山西云时代技术有限公司校园招聘笔试备考题库及答案解析
- GB/T 713.7-2023承压设备用钢板和钢带第7部分:不锈钢和耐热钢
- 全国小学信息技术优质课教学课件-语音识别技术
- CT增强扫描的临床应用演示文稿
- 2023学年完整公开课版船舶防污漆
- 抗菌药物临床应用指导原则(2015版)
- 包装危险货物技术说明书
- 石灰石矿山破碎系统施工方案
- 新教材人教版2019年高中生物课本课后问题参考答案(全集)
评论
0/150
提交评论