到这里,看到所有的配置是借助SpringFactoriesLoader加载了META-INF/spring.factories文件里面所有符合条件的配置项的全路径名。
找到spring-boot-autoconfigure包,看到META-INF下的spring.factories文件(果然是你,果然),这里就是自动化配置所有类项的列表。/** * General purpose factory loading mechanism for internal use within the framework. * *{
@code SpringFactoriesLoader} { @linkplain #loadFactories loads} and instantiates * factories of a given type from { @value #FACTORIES_RESOURCE_LOCATION} files which * may be present in multiple JAR files in the classpath. The { @code spring.factories} * file must be in { @link Properties} format, where the key is the fully qualified * name of the interface or abstract class, and the value is a comma-separated list of * implementation class names. For example: * *example.MyService=example.MyServiceImpl1,example.MyServiceImpl2* * where { @code example.MyService} is the name of the interface, and { @code MyServiceImpl1} * and { @code MyServiceImpl2} are two implementations. * * @author Arjen Poutsma * @author Juergen Hoeller * @author Sam Brannen * @since 3.2 */public abstract class SpringFactoriesLoader { private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class); /** * The location to look for factories. *Can be present in multiple JAR files. */ public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
org.springframework.boot.autoconfigure.SpringBootApplication
之@EnableAutoConfigurationpackage org.springframework.boot.autoconfigure;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Inherited;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import org.springframework.boot.SpringBootConfiguration;import org.springframework.boot.context.TypeExcludeFilter;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.ComponentScan.Filter;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.FilterType;import org.springframework.core.annotation.AliasFor;/** * Indicates a { @link Configuration configuration} class that declares one or more * { @link Bean @Bean} methods and also triggers { @link EnableAutoConfiguration * auto-configuration} and { @link ComponentScan component scanning}. This is a convenience * annotation that is equivalent to declaring { @code @Configuration}, * { @code @EnableAutoConfiguration} and { @code @ComponentScan}. * * @author Phillip Webb * @author Stephane Nicoll * @since 1.2.0 */@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 { /** * Exclude specific auto-configuration classes such that they will never be applied. * @return the classes to exclude */ @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "exclude") Class [] exclude() default {}; /** * Exclude specific auto-configuration class names such that they will never be * applied. * @return the class names to exclude * @since 1.3.0 */ @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "excludeName") String[] excludeName() default {}; /** * Base packages to scan for annotated components. Use { @link #scanBasePackageClasses} * for a type-safe alternative to String-based package names. * @return base packages to scan * @since 1.3.0 */ @AliasFor(annotation = ComponentScan.class, attribute = "basePackages") String[] scanBasePackages() default {}; /** * Type-safe alternative to { @link #scanBasePackages} for specifying the packages to * scan for annotated components. The package of each class specified will be scanned. ** Consider creating a special no-op marker class or interface in each package that * serves no purpose other than being referenced by this attribute. * @return base packages to scan * @since 1.3.0 */ @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses") Class
[] scanBasePackageClasses() default {};}
org.springframework.boot.autoconfigure.EnableAutoConfiguration
package org.springframework.boot.autoconfigure;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Inherited;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;import org.springframework.context.annotation.Conditional;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;import org.springframework.core.io.support.SpringFactoriesLoader;/** * Enable auto-configuration of the Spring Application Context, attempting to guess and * configure beans that you are likely to need. Auto-configuration classes are usually * applied based on your classpath and what beans you have defined. For example, If you * have { @code tomcat-embedded.jar} on your classpath you are likely to want a * { @link TomcatEmbeddedServletContainerFactory} (unless you have defined your own * { @link EmbeddedServletContainerFactory} bean). ** Auto-configuration tries to be as intelligent as possible and will back-away as you * define more of your own configuration. You can always manually {
@link #exclude()} any * configuration that you never want to apply (use { @link #excludeName()} if you don't * have access to them). You can also exclude them via the * { @code spring.autoconfigure.exclude} property. Auto-configuration is always applied * after user-defined beans have been registered. ** The package of the class that is annotated with {
@code @EnableAutoConfiguration} has * specific significance and is often used as a 'default'. For example, it will be used * when scanning for { @code @Entity} classes. It is generally recommended that you place * { @code @EnableAutoConfiguration} in a root package so that all sub-packages and classes * can be searched. ** Auto-configuration classes are regular Spring {
@link Configuration} beans. They are * located using the { @link SpringFactoriesLoader} mechanism (keyed against this class). * Generally auto-configuration beans are { @link Conditional @Conditional} beans (most * often using { @link ConditionalOnClass @ConditionalOnClass} and * { @link ConditionalOnMissingBean @ConditionalOnMissingBean} annotations). * * @author Phillip Webb * @author Stephane Nicoll * @see ConditionalOnBean * @see ConditionalOnMissingBean * @see ConditionalOnClass * @see AutoConfigureAfter */@SuppressWarnings("deprecation")@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage@Import(EnableAutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; /** * Exclude specific auto-configuration classes such that they will never be applied. * @return the classes to exclude */ Class [] exclude() default {}; /** * Exclude specific auto-configuration class names such that they will never be * applied. * @return the class names to exclude * @since 1.3.0 */ String[] excludeName() default {};}
org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector
package org.springframework.boot.autoconfigure;import org.springframework.context.annotation.DeferredImportSelector;import org.springframework.core.type.AnnotationMetadata;/** * { @link DeferredImportSelector} to handle { @link EnableAutoConfiguration * auto-configuration}. This class can also be subclassed if a custom variant of * { @link EnableAutoConfiguration @EnableAutoConfiguration}. is needed. * * @deprecated as of 1.5 in favor of { @link AutoConfigurationImportSelector} * @author Phillip Webb * @author Andy Wilkinson * @author Stephane Nicoll * @author Madhura Bhave * @since 1.3.0 * @see EnableAutoConfiguration */@Deprecatedpublic 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; }}
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports@Override public String[] selectImports(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } try { AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadMetadata(this.beanClassLoader); AnnotationAttributes attributes = getAttributes(annotationMetadata); Listconfigurations = getCandidateConfigurations(annotationMetadata, attributes); configurations = removeDuplicates(configurations); configurations = sort(configurations, autoConfigurationMetadata); Set exclusions = getExclusions(annotationMetadata, attributes); checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = filter(configurations, autoConfigurationMetadata); fireAutoConfigurationImportEvents(configurations, exclusions); return configurations.toArray(new String[configurations.size()]); } catch (IOException ex) { throw new IllegalStateException(ex); } }
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getCandidateConfigurations
/** * Return the auto-configuration class names that should be considered. By default * this method will load candidates using { @link SpringFactoriesLoader} with * { @link #getSpringFactoriesLoaderFactoryClass()}. * @param metadata the source metadata * @param attributes the { @link #getAttributes(AnnotationMetadata) annotation * attributes} * @return a list of candidate configurations */ protected ListgetCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List 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; }
org.springframework.core.io.support.SpringFactoriesLoader#loadFactoryNames
/** * Load the fully qualified class names of factory implementations of the * given type from { @value #FACTORIES_RESOURCE_LOCATION}, using the given * class loader. * @param factoryClass the interface or abstract class representing the factory * @param classLoader the ClassLoader to use for loading resources; can be * { @code null} to use the default * @see #loadFactories * @throws IllegalArgumentException if an error occurs while loading factory names */ public static ListloadFactoryNames(Class factoryClass, ClassLoader classLoader) { String factoryClassName = factoryClass.getName(); try { Enumeration urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION)); List result = new ArrayList (); while (urls.hasMoreElements()) { URL url = urls.nextElement(); Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url)); String factoryClassNames = properties.getProperty(factoryClassName); 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); } }
org.springframework.core.io.support.SpringFactoriesLoader#FACTORIES_RESOURCE_LOCATION
/** * General purpose factory loading mechanism for internal use within the framework. * *{
@code SpringFactoriesLoader} { @linkplain #loadFactories loads} and instantiates * factories of a given type from { @value #FACTORIES_RESOURCE_LOCATION} files which * may be present in multiple JAR files in the classpath. The { @code spring.factories} * file must be in { @link Properties} format, where the key is the fully qualified * name of the interface or abstract class, and the value is a comma-separated list of * implementation class names. For example: * *example.MyService=example.MyServiceImpl1,example.MyServiceImpl2* * where { @code example.MyService} is the name of the interface, and { @code MyServiceImpl1} * and { @code MyServiceImpl2} are two implementations. * * @author Arjen Poutsma * @author Juergen Hoeller * @author Sam Brannen * @since 3.2 */public abstract class SpringFactoriesLoader { private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class); /** * The location to look for factories. *Can be present in multiple JAR files. */ public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";