这个是spring的ioc容器启动类
spring中一个类可以加载到spring容器中的几种方法
@SpringBootConfiguration==Configuration 表示 被Bean 修饰的类可以被加载到spring 的容器中
@EnableAutoConfiguration =这个注解是关键
@Import({Registrar.class}) @Import({EnableAutoConfigurationImportSelector.class})
重点的一个Import注解: 加载一个类,如果当前的类实现了 ImportSelector
那么spring的ioc容器就不加载EnableAutoConfigurationImportSelector 这个类 而是加载
ImportSelector#String[] selectImports(AnnotationMetadata importingClassMetadata);返回对应类的全名到spring的容器中
比如:
或者 另外一种实现方式
static class Registrar implements ImportBeanDefinitionRegistrar,实现 ImportBeanDefinitionRegistrar 这个接口 public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry)
所以自动装配的核心就是 import注解对应类中的方法 EnableAutoConfigurationImportSelector,
//加载 这个配置文件对应的类META-INF/spring-autoconfigure-metadata.properties 主要设置的是
spring自动装配类的条件,主要会影响spring.factories需要加载类的条件
public static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader) { return loadMetadata(classLoader, "META-INF/spring-autoconfigure-metadata.properties"); }
其中这个配置文件中的数据
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration=
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration.ConditionalOnClass=org.springframework.amqp.rabbit.core.RabbitTemplate,com.rabbitmq.client.Channel
ConditionalOnClass---加载这个类的前提是需要有这个类的存在
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration.AutoConfigureAfter=org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration
AutoConfigureAfter ---加载这个类之后 在加载这个某个类
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration.AutoConfigureBefore=org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration
AutoConfigureBefore--加载这个类之前需要加载这个类
//加载 当前项目下所有的 META-INF/spring.factories 比如当前spring的 mybtais-spring的spring.factories
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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; }
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
try {
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
//加载所有类,加载spring.factories中所有的类
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
//删除重名 包名.类名的
configurations = this.removeDuplicates(configurations);
configurations = this.sort(configurations, autoConfigurationMetadata);
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
//目前过滤掉128个类中的几个 META-INF/spring-autoconfigure-metadata.properties
//只会加载这个里面的文件
configurations = this.filter(configurations, autoConfigurationMetadata);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return (String[])configurations.toArray(new String[configurations.size()]);
} catch (IOException var6) {
throw new IllegalStateException(var6);
}
}
}
一个文件中的类是否被加载,可以使用conditional
总结一句话:加载spring.factories 类 然后使用META-INF/spring-autoconfigure-metadata.properties 这个配置的类进行条件过滤