Spring Boot run()方法剖析
Spring Boot自动配置部分重点介绍了相关注解,关于main中调用的run方法并没有阐述过。run方法的作用是什么呢?只有注解没有main里的run方法Spring Boot工程就好比身体个方面机能都比较好除了大脑不工作的植物人;run方法指挥各项注解有序进行工作。
下面分析Spring Boot中的run方法如何指挥工作:
1、SpringApplication() 构造方法
2、run方法详解
下面以Eureka服务启动为例,详述run方法每个关键动作都发挥了什么作用。调试Eureka服务端启动:
第一步:获取并启动监听器
EventPublishingRunListener监听器是Spring容器的启动监听器,listeners.starting()开启了监听事件。那么开启监听了哪类事件呢?通过源码具体可以分析出如下结果:
多播ApplicationStartingEvent,同时使用Consumer函数式接口处理。
在Spring Bean配置加载为BeanDefinition全过程(注解配置) - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中详述注解方式BeanIOC的过程,下面步骤基本就是bean注册的一个过程,底层基本一致。比如第五步中底层使用的就是spring中的refresh方法,可以参考五、模板方法设计模式及在Spring中的应用 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)
第二步:构造应用上下文环境
第三步:初始化应用上下文
根据应用类型创建一个AnnotationConfigServletWebServerApplicationContext容器:
第四步:刷新应用上下文前的准备阶段
第五步:刷新应用上下文
其中,注解说明该onRefresh()的作用是在容器子类中初始化其他特别的bean,通过调试及控制台日志信息可以知道初始化了哪些特殊的bean:
相关bean最终初始化在完成。但此时Eureka服务并没有启动,refresh还差最后异步finishRefresh(对于Eureka而言至关重要参考Eureka Server启动过程 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com))。
第六步:刷新应用上下文后的扩展接口
扩展接口,设计模式中的模板方法,默认为空实现。如果有自定义需求,可以重写该方法。比如打印一些启动结束log,或者一些其它后置处理。
未完,待续……