无论使用哪种方式,最终都会使用ClassPathBeanDefinitionScanner.doScan()方法
使用JavaConfig方式
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(XXX.class);
分成两步:
- 先加载主类这个BeanDefinition –
register()
- 再根据主类上的
@ComponentScan("xxx.yy")
去扫描加载 –refresh()
第一步在AnnotationConfigApplicationContext
的构造器中的register(componentClasses)
方法中完成
第二步在下面步骤中完成
refresh()
->invokeBeanFactoryPostProcessors()
->PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()
->ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry//有多个相似的处理器,Component相关的注解使用现在这个处理器
->processConfigBeanDefinitions()
->ConfigurationClassParser.parse()
->parse(AnnotationMetadata metadata, String beanName)//方法重载,注意这里是AnnotationMetadata
->doProcessConfigurationClass()
->ComponentScanAnnotationParser.parse()
->ClassPathBeanDefinitionScanner.doScan()
使用扫描包位置方式
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("xxx.yy");
会直接在构造器中的scan(basePackages)
方法中扫描出所有的类