springboot开发真的非常简洁, 对比以前开发配置一大推配置文件,但是我们要知道springboot是怎么样做到自动装配的,是怎么把我们需要配置到配置文件的bean直接帮我们自动注入进去的
- @SpringBootApplication
- @ComponentScan(basePackages = {"com.zx"})
- public class SpMpApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(SpMpApplication.class, args);
- }
-
- }
先从表象分析,很明显springboot启动类上面添加 了注解,先从该注解分析查看
@Configuration
@Import({AutoConfigurationImportSelector.class}) @Import 导入了AutoConfigurationImportSelector.class , 这个类实现了 ImportSelector接口,就会重写 selectImports 方法 ,我们找到该方法的实现


主要看一下
this.getCandidateConfigurations(annotationMetadata, attributes); 方法

这里就是去加载我们的配置META-INF/spring.factories文件里面的自动装配的类的全路径(有了类的全路径,啥都可以干了)

分析到这里,其实大体流程就已经完毕了,
其实说到底springboot就很好的借助spring的功能,在进行封装,我们只需要引入相关的starter.jar
创建META-INF/spring.factories文件,添加需要配置的类路径即可
- # Auto Configure
- org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
- com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration
首先你的了解spring创建bean的流程(看下图): 收集所有需要创建的bean,生成BeanDefinition对象,该对象里面包含了类的信息,拿到所有的BeanDefinition集合之后 , 再根据bean定义的内容反射创建bean -- 所以如果我们想要新增bean,就得注册bean定义,bean工厂也提供了对应的后置处理器方法,我们可以去修改,注册bean定义 ( 别人设计是非常灵活的)

如果单独使用过spring的应该知道,首先的创建一个上下文对象,把配置类传进去
AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(ApplicationRun.class);


创建一个bean定义的Reader,继续跟进去

注册配置类,继续跟进去该方法

发现spring帮我们注册了一个beandefinition => ConfigurationClassPostProcessor.class

ConfigurationClassPostProcessor实现了 BeanDefinitionRegistryPostProcessor 类,就会重写postProcessBeanDefinitionRegistry方法

执行beanFactoryPostprocessors方法

执行bean工厂的后置处理器方法了


注意看, 这里会判断 ,是否为PriorityOrdered类型,会先执行该类型的方法
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class))

接下来会执行Ordered

,最后执行普通的
注意: 这里不会重复执行的奥,因为这里进行了判断的, 如果已经执行了的,就不会在执行

开始执行
postProcessBeanDefinitionRegistry方法了
最后执行bean工厂后置处理器方法
postProcessor.postProcessBeanFactory(beanFactory);
这也就是为啥spring会执行到我们实现的这些接口的方法, 是因为在这里有一个循环遍历的调用
所以上面spring注册的ConfigurationClassPostProcessor.class就会调用到他的方法,进入该代码中

这里是一个循环执行,当循环执行完毕之后,就会执行最后的方法
this.deferredImportSelectorHandler.process();




现在已经把@Import注解上面需要导入的类,扫描完之后还并没有完, 如果这里面是实现了
ImportSelector接口的话,还得要执行 selectImports 方法, 该方法会返回需要注册的bean定义信息

这里就是去调用 ImportSelector接口的实现方法: selectImports

把扫描出来的这些类信息,封装为beandefinition对象 , 成为了beandefinition对象之后, beanfactory就会创建bean拉

整体就已经完结拉
自己的理解可能某些地方会有问题恳请指出!