SpringBoot 在启动时会扫描外部引用 jar 包中的META-INF/spring.factories
文件,将文件中配置的类型信息加载到 Spring 容器
在springBoot启动类上有一个复合注解@SpringBootApplication
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication {
@SpringBootApplication中有三个注解
1、@SpringBootConfiguration:允许在上下文注册额外的bean或者引入其他的配置
2、@EnableAutoConfiguration 启动springBoot自动装配
3、ComponentScan:扫描注解的类(@Component、@Service、@Controller),排除使用excludeFilters
@AutoConfigurationPackage //作用:将main包下的所欲组件注册到容器中 @Import({AutoConfigurationImportSelector.class}) //加载自动装配类 xxxAutoconfiguration public @interface EnableAutoConfiguration {
引入AutoConfigurationImportSelector 实现自动装配
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered { }
public interface DeferredImportSelector extends ImportSelector {}
public interface ImportSelector { String[] selectImports(AnnotationMetadata importingClassMetadata); }
AutoConfigurationImportSelector实现了DefaultImportSelector,最终实现ImportSelector 执行selectImports方法
在AutoConfigurationImportSelector 实现中
public String[] selectImports(AnnotationMetadata annotationMetadata) { //判断是否开始自动装配 if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } //获取所有自动装配的bean AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata); return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); }
在getAutoConfigurationEntry方法中获取需要装配的bean
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) { //1、是否开启自动装配 if (!isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } //2、用于获取EnableAutoConfiguration注解中的 exclude 和 excludeName AnnotationAttributes attributes = getAttributes(annotationMetadata); //3、获取需要自动装配的所有配置类,读取META-INF/spring.factories List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); //4、筛选所有自动装配的bean 只有符合条件的才可以引入:@ConditionalOnXXX 中的所有条件都满足,该类才会生效。 configurations = removeDuplicates(configurations); Set<String> exclusions = getExclusions(annotationMetadata, attributes); checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = getConfigurationClassFilter().filter(configurations); fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions); }
获取所有候选的配置,候选的配置来源就是方法实现中的
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + "are using a custom packaging, make sure that file is correct."); return configurations; }
loadFactoryNames获取所有的配置类,如果配置信息是空的,就会抛出异常说在META-INF/spring.factories中没有配置信息;就剋看出在这里加载的是spring.factories下的配置信息