SpringBoot启动分析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot启动分析相关的知识,希望对你有一定的参考价值。
参考技术A SpringApplication.run方法中,实例化一个SpringApplication对象,并调用该对象的run方法。在SpringApplication构造函数中,主要完成了这样两件事:
在run()中主要完成如下几项工作:
在refreshContext方法中实现Ioc容器的初始化和Ioc的依赖注入。其中,在invokeBeanFactoryPostProcessors()方法中完成了IoC容器初始化过程的三个步骤。
第一步:Resource定位
在SpringBoot中,我们都知道他的包扫描是从主类所在的包开始扫描的,prepareContext()方法中,会先将主类解析成BeanDefinition,然后在refresh()方法的invokeBeanFactoryPostProcessors()方法中解析主类的BeanDefinition获取basePackage的路径。这样就完成了定位的过程。其次SpringBoot的各种starter是通过SPI扩展机制实现的自动装配,SpringBoot的自动装配同样也是在invokeBeanFactoryPostProcessors()方法中实现的。还有一种情况,在SpringBoot中有很多的@EnableXXX注解,细心点进去看的应该就知道其底层是@Import注解,在invokeBeanFactoryPostProcessors()方法中也实现了对该注解指定的配置类的定位加载。
常规的在SpringBoot中有三种实现定位,第一个是主类所在包的,第二个是SPI扩展机制实现的自动装配(比如各种starter),第三种就是@Import注解指定的类。
第二步:BeanDefinition的载入
在第一步中说了三种Resource的定位情况,定位后紧接着就是BeanDefinition的分别载入。所谓的载入就是通过上面的定位得到的basePackage,SpringBoot会将该路径拼接成:classpath :org/springframework/boot/demo/ / .class这样的形式,然后一个叫做PathMatchingResourcePatternResolver的类会将该路径下所有的.class文件都加载进来,然后遍历判断是不是有@Component注解,如果有的话,就是我们要装载的BeanDefinition。大致过程就是这样的了。
TIPS:@Configuration,@Controller,@Service等注解底层都是@Component注解,只不过包装了一层罢了。
第三步:注册BeanDefinition
这个过程通过调用上文提到的BeanDefinitionRegister接口的实现来完成。这个注册过程把载入过程中解析得到的BeanDefinition向IoC容器进行注册。通过上文的分析,我们可以看到,在IoC容器中将BeanDefinition注入到一个ConcurrentHashMap中,IoC容器就是通过这个HashMap来持有这些BeanDefinition数据的。比如DefaultListableBeanFactory 中的beanDefinitionMap属性。
invokeBeanFactoryPostProcessors方法中主要通过ConfigurationClassPostProcessor完成IoC容器初始化的过程。
registerBeanPostProcessors方法中注册了AutowiredAnnotationBeanPostProcessor,registerBeanPostProcessors方法中对bean进行初始化时会调用AutowiredAnnotationBeanPostProcessor的接口实现@Autowired,完成Ioc的注入。
参考:
https://www.cnblogs.com/hello-shf/p/10992377.html
https://www.jianshu.com/p/b86a7c8b3442
以上是关于SpringBoot启动分析的主要内容,如果未能解决你的问题,请参考以下文章