Spring Boot的自动配置实现由启动类上@SpringBootApplication注解中@EnableAutoConfiguration注解中的@Import(EnableAutoConfigurationImportSelector.class)注解导入的EnableAutoConfigurationImportSelector实现的。
1.5版本以前使用EnableAutoConfigurationImportSelector类,1.5以后这个类标识过时了,但在1.5之后代码中还是用该类,且该类中没有了核心实现,而在其父类AutoConfigurationImportSelector中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 // 我采用的版本:1.5.14.RELEASE @SuppressWarnings("deprecation") @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(EnableAutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<?>[] exclude() default {}; String[] excludeName() default {}; } @Deprecated public class EnableAutoConfigurationImportSelector extends AutoConfigurationImportSelector { @Override protected boolean isEnabled(AnnotationMetadata metadata) { if (getClass().equals(EnableAutoConfigurationImportSelector.class)) { return getEnvironment().getProperty( EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class, true); } return true; } }
AutoConfigurationImportSelector会使用SpringFactoriesLoader.loadFactoryNames方法来扫描具有MEAT-INF/spring.factories文件的jar包。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // AutoConfigurationImportSelector类中的方法 protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { // 第一参数:EnableAutoConfiguration.class类字节码,如下 // 第二参数:类加载器 // 返回所有自动配置类全类名,具体实现看下文 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; } protected Class<?> getSpringFactoriesLoaderFactoryClass() { return EnableAutoConfiguration.class; }
SpringFactoriesLoader类的静态方法loadFactoryNames()实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories"; public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) { // 返回org.springframework.boot.autoconfigure.EnableAutoConfiguration字符串 String factoryClassName = factoryClass.getName(); try { // 通过ClassLoader获取META-INF/spring.factories资源文件 Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION)); List<String> result = new ArrayList<String>(); while (urls.hasMoreElements()) { URL url = urls.nextElement(); // 把URL转成Properties Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url)); // 获取属性文件中key为EnableAutoConfiguration全类名的值,该值是逗号分隔的类全名字符串,它们是spring整合的自动配置类 String factoryClassNames = properties.getProperty(factoryClassName); // 封装所有自动配置类全类名到List,并返回 result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames))); } return result; } catch (IOException ex) { throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() + "] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex); } }
spring-boot-autoconfigure-1.5.14.RELEASE.jar中META-INF/spring.factories文件部分内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # Initializers org.springframework.context.ApplicationContextInitializer=\ org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\ org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer # Application Listeners org.springframework.context.ApplicationListener=\ org.springframework.boot.autoconfigure.BackgroundPreinitializer # Auto Configuration Import Listeners org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\ org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener # Auto Configuration Import Filters org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\ org.springframework.boot.autoconfigure.condition.OnClassCondition # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\ org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
其实就是一个属性文件,左侧通常为一个接口或者是一个注解类,右侧为接口的实现,或者是和左值相关的注解。
Auto Configure注释下都是自动配置类,SpringBoot会根据这些自动配置类去自动配置环境,如对redis和mongo的自动配置类。