我们都知道在SpringBoot启动类上添加@SpringBootApplication注解后执行main方法就可以自动启动服务 Spring会自动帮我们找到需要管理的Bean的呢
经典的八股文AbstractApplicationContext#refresh()方法 相信大家已经比较熟悉了
进入invokeBeanFactoryPostProcessors()调用BeanFactory后置处理器方法
ClassPathBeanDefinitionScanner#doScan 继续往里 还是那句 红线标注的地方
ClassPathScanningCandidateComponentProvider#scanCandidateComponents 好了 到站 请各位乘客下车吧 这个方法就是真实找到底层bean的地方 原理很简单 参数basePackage为我们的包根路径 即启动类所在的路径 假设为com/juejin/drink 那么此方法会递归调用扫描com/juejin/drink下的所有类和目录 如果是需要注册的bean 那么放入new的LinkedHashSet中返回
经过如上步骤 程序会返回到PostProcessorRegistrationDelegate的invokeBeanDefinitionRegistryPostProcessors方法继续执行 但此时我们的目的达到了 实际上SpringBoot就是通过@SpringBootApplication的@CompentScan注解 拿到启动类的包路径 最终去递归调用 获取到哪些是我们标注了@Compent这些需要注册进容器的 此步骤是refresh方法的invokeBeanFactoryPostProcessors()中执行的
本文只是简单的叙述了下Spring是如何将我们的Bean加载到beanDefinitionMap中的 比较简单 不涉及其他复杂逻辑