先看一下注解部分:
1. 先从注解 @SpringBootApplication开始
@SpringBootApplication详解
1) @SpringBootConfiguration:SpringBoot的配置类;标注在某个类上,表示这是一个SpringBoot的配置类;
在@SpringBootConfiguration的定义上有一个@Configuration 表示这个类是一个配置类;
2) @ComponentScan即在Spring中见过的包扫描注解。excludeFilters 是其中一个配置项,用于排除不需要扫描的类
3) @EnableAutoConfiguration:开启自动配置功能; 以前我们需要配置的东西,SpringBoot帮我们自动配置; 这个注解中有: @AutoConfigurationPackage 作用是将添加该注解的类所在的package作为自动配置package 进行管理
@Import(AutoConfigurationImportSelector.class)
2. 重点来跟踪一下: @Import({AutoConfigurationImportSelector.class})
1. @EnableAutoConfiguration里通过@Import导入了AutoConfigurationImportSelector
2. AutoConfigurationImportSelector类中有一个 重点来了: **** selectImports(AnnotationMetadata annotationMetadata)方法, 这个方法调用了 : getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata); 在这个方法中调用了: List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); 获取所有的配置项 那么它是怎么获取的呢?
3. 再观察: getCandidateConfigurations(annotationMetadata, attributes); 其中有 List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader());
4. 再进入SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader()); 可以看到它取出工厂类型名后,调用了 loadSpringFactories(classLoader) 它的返回值是一个Map, 在这个方法中有: Enumeration<URL> urls = (classLoader != null ?classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
请观察: classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : 从这里可以看到 类加载器在加载 路径: FACTORIES_RESOURCE_LOCATION="META-INF/spring.factories"
就这里了, 请到 "META-INF/spring.factories" 查看,在这个文件中,可以看到一系列Spring Boot自动配置的列表.
再看一下 springBoot的运行部分
1. SpringApplication.run() ->
SpringApplication类的 316行: refreshContext(context); ->
397行: refresh(context);
775行: ((AbstractApplicationContext) applicationContext).refresh();
2. 所以查看 AbstractApplicationContext类的源码:
528行: invokeBeanFactoryPostProcessors(beanFactory); 这个方法启动工厂处理器以注册bean到容器
691行: 在invokeBeanFactoryPostProcessors()方法中 调用 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
在这个方法的 130行 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
286行: for (BeanFactoryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanFactory(beanFactory); } 注意: 这里的 BeanFactoryPostProcessor是一个接口,它下面的 org.springframework.context.annotation.ConfigurationClassPostProcessor 类才是我们要看的.
3. ConfigurationClassPostProcessor类的 postProcessBeanFactory(beanFactory); 方法中的
250行: processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory); 处理有注解的Bean的定义 从processConfigBeanDefinitions()方法中的 307行开始解析 @Configuration注解了,
注意: 315行 parser.parse(candidates); 这里的parser是一个 ConfigurationClassParser 即对加了 @Configuration的类的解析器. 这里的 candidates是 274行读取的这些被 @Configuration注解的类.
4. parser是一个 org.springframework.context.annotation.ConfigurationClassParser类的对象 上面 parser.parse(candidates) 中 调用context.annotation.ConfigurationClassParser.doProcessConfigurationClass()方法处理ConfigurationClass:
从 167行 -> 199行 -> 242行 -> sourceClass = doProcessConfigurationClass(configClass, sourceClass); 按类层次结构追踪 处理ConfigurationClass,
请具体分析以下这个源码: doProcessConfigurationClass(configClass, sourceClass),在它里面,它处理了: 1. @PropertySource
2. @ComponentScan
3. @Import 注意这个, 与我们讲的 springboot中的 @Import(AutoConfigurationImportSelector.class) 相关 4. @ImportResource
5. @Bean
5. 接上面的 3 对@Import的处理
302行 processImports(configClass, sourceClass, getImports(sourceClass), true);
到 544行, 遍历每个@Import标签,生成被注入的ImportSelector子类的实例
注意从 560行到 566行: |
-> 对于普通ImportSelector,调用其selectImport()方法,筛掉exclude的,再嵌套processImports(),对需要被@Import的类的@Import注解进行处理 |
-> 对于DefferedImportSelector,只加入deferredImportSelectors列表中
特别是 569行 String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata()); 这里调用的就是 springboot中提到的注解了