前言:
springboot开发真的非常简洁, 对比以前开发配置一大推配置文件,但是我们要知道springboot是怎么样做到自动装配的,是怎么把我们需要配置到配置文件的bean直接帮我们自动注入进去的
@SpringBootApplication
@ComponentScan(basePackages = {"com.zx"})
public class SpMpApplication {
public static void main(String[] args) {
SpringApplication.run(SpMpApplication.class, args);
}
}
分析springboot
分析注解
先从表象分析,很明显springboot启动类上面添加 了注解,先从该注解分析查看
- @SpringBootApplication 启动类上面添加了该注解
- @SpringBootConfiguration
-
@Configuration
-
- @EnableAutoConfiguration
-
@Import({AutoConfigurationImportSelector.class})
-
- @SpringBootConfiguration
@Import 导入了AutoConfigurationImportSelector.class , 这个类实现了 ImportSelector接口,就会重写 selectImports 方法 ,我们找到该方法的实现
分析AutoConfigurationImportSelector类
主要看一下
this.getCandidateConfigurations(annotationMetadata, attributes); 方法
这里就是去加载我们的配置META-INF/spring.factories文件里面的自动装配的类的全路径(有了类的全路径,啥都可以干了)
分析到这里,其实大体流程就已经完毕了,
捋一下大体逻辑
- 通过@Import 注解导入AutoConfigurationImportSelector类
- 该类实现 ImportSelector接口 ,就会重写 selectImports 方法
- selectImports方法里面就会去读取配置文件META-INF/spring.factories里面配置的EnableAutoConfiguration对应的类路径
- 进行一些过滤,去重之后再返回
其实说到底springboot就很好的借助spring的功能,在进行封装,我们只需要引入相关的starter.jar
创建META-INF/spring.factories文件,添加需要配置的类路径即可
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration
接下来就是说 spring的执行流程,spring是怎么去执行ImportSelector的方法的
创建bean的流程
首先你的了解spring创建bean的流程(看下图): 收集所有需要创建的bean,生成BeanDefinition对象,该对象里面包含了类的信息,拿到所有的BeanDefinition集合之后 , 再根据bean定义的内容反射创建bean -- 所以如果我们想要新增bean,就得注册bean定义,bean工厂也提供了对应的后置处理器方法,我们可以去修改,注册bean定义 ( 别人设计是非常灵活的)
分析执行流程:
如果单独使用过spring的应该知道,首先的创建一个上下文对象,把配置类传进去
AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(ApplicationRun.class);
this方法 : 注册ConfigurationClassPostProcessor.class
创建一个bean定义的Reader,继续跟进去
注册配置类,继续跟进去该方法
发现spring帮我们注册了一个beandefinition => ConfigurationClassPostProcessor.class
ConfigurationClassPostProcessor实现了 BeanDefinitionRegistryPostProcessor 类,就会重写postProcessBeanDefinitionRegistry方法
refersh()方法 核心方法
执行beanFactoryPostprocessors方法
执行bean工厂的后置处理器方法了
注意看, 这里会判断 ,是否为PriorityOrdered类型,会先执行该类型的方法
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class))
接下来会执行Ordered
,最后执行普通的
注意: 这里不会重复执行的奥,因为这里进行了判断的, 如果已经执行了的,就不会在执行
开始执行
postProcessBeanDefinitionRegistry方法了
最后执行bean工厂后置处理器方法
postProcessor.postProcessBeanFactory(beanFactory);
这也就是为啥spring会执行到我们实现的这些接口的方法, 是因为在这里有一个循环遍历的调用
spring 执行bean工厂后置处理器方法
所以上面spring注册的ConfigurationClassPostProcessor.class就会调用到他的方法,进入该代码中
这里是一个循环执行,当循环执行完毕之后,就会执行最后的方法
this.deferredImportSelectorHandler.process();
现在已经把@Import注解上面需要导入的类,扫描完之后还并没有完, 如果这里面是实现了
ImportSelector接口的话,还得要执行 selectImports 方法, 该方法会返回需要注册的bean定义信息
这里就是去调用 ImportSelector接口的实现方法: selectImports
把扫描出来的这些类信息,封装为beandefinition对象 , 成为了beandefinition对象之后, beanfactory就会创建bean拉
整体就已经完结拉
结束语:
自己的理解可能某些地方会有问题恳请指出!