springboot 自动配置
1.@SpringBootApplication 注解
//SpringBootApplication.java
/**
* 表示一个声明一个或多个的 {@link Configuration configuration} 类
* {@link Bean @Bean}方法并触发{@link EnableAutoConfiguration
* 自动配置}和{@link ComponentScan 组件扫描}。这很方便
* 等同于声明 {@code @Configuration} 的注释,* {@code @EnableAutoConfiguration}和{@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 {
/**
* 排除特定的自动配置类,使其永远不会应用。* @return the classes to exclude
*/
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
/**
* 排除特定的自动配置类名称,使它们永远不会
* 适用。* @return the class names to exclude
* @since 1.3.0
*/
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
/**
* 基本软件包以扫描带注释的组件。使用{@link #scanBasePackageClasses}
* 用于基于字符串的软件包名称的类型安全替代。* @return base packages to scan
* @since 1.3.0
*/
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
/**
* {@link #scanBasePackages}的类型安全替代品,用于指定要
* 扫描带注释的组件。指定类别的包装将被扫描。* <p>
* 考虑在每个程序包中创建一个特殊的无操作标记类或接口
* 除了被该属性引用以外,没有其他用途。* @return base packages to scan
* @since 1.3.0
*/
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};}
如果使用自动配置功能就必须引用这个注解。
1.1SpringBootConfiguration
//SpringBootConfiguration
/**
* 表示一个类提供了 Spring Boot 应用程序
* {@link 配置 @Configuration}。可以用作弹簧的替代品
* 标准 {@code @Configuration} 批注,以便可以找到配置
* 自动(例如在测试中)。* <p>
* 应用程序仅应包含 <em> one </ em> {@code @SpringBootConfiguration}和
* 大多数惯用的 Spring Boot 应用程序将从其继承它
* {@code @SpringBootApplication}.
*
* @author Phillip Webb
* @since 1.4.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {}
1.2@ComponentScan
该注解,扫描指定路径下的 Component(@Componment
、@Configuration
、@Service
等等)。
1.3@EnableAutoConfiguration
//EnableAutoConfiguration.java
/**
* 启用 Spring Application Context 的自动配置,尝试猜测和
* 配置您可能需要的 bean。自动配置类通常是
* 根据您的类路径和定义的 bean 来应用。例如,如果您
* 您的类路径上可能有{@code tomcat-embedded.jar}
* {@link TomcatServletWebServerFactory}(除非您已定义了自己的
* {@link ServletWebServerFactory} bean)。* <p>
* 使用 {@link SpringBootApplication} 时,上下文的自动配置为
* 自动启用并添加此注释因此没有其他效果。* <p>
* 自动配置会尝试尽可能智能化,并且会像您一样落后
* 定义更多您自己的配置。您随时可以手动{@link #exclude()}
* 您永远不想应用的配置(如果不使用,请使用{@link #excludeName()}
* 可以访问它们)。您也可以通过
* {@code spring.autoconfigure.exclude}属性。始终应用自动配置
* 在注册用户定义的 bean 之后。* <p>
* 用 {@code @EnableAutoConfiguration} 注释的类的程序包,* 通常通过 {@code @SpringBootApplication} 进行,具有特定的意义并且经常使用
* 作为“默认值”。例如,在扫描 {@code @Entity} 类时将使用它。* 通常建议您放置{@code @EnableAutoConfiguration}(如果您
* 不要在根包中使用{@code @SpringBootApplication}),以便所有子包
* 和类别可以搜索。* <p>
* 自动配置类是常规的 Spring {@link Configuration} bean。他们是
* 使用 {@link SpringFactoriesLoader} 机制定位(针对此类)。* 通常,自动配置 Bean 是{@link 条件 @Conditional} Bean(大多数
* 经常使用 {@link ConditionalOnClass @ConditionalOnClass} 和
* {@link ConditionalOnMissingBean @ConditionalOnMissingBean}注释)。*
* @author Phillip Webb
* @author Stephane Nicoll
* @since 1.0.0
* @see ConditionalOnBean
* @see ConditionalOnMissingBean
* @see ConditionalOnClass
* @see AutoConfigureAfter
* @see SpringBootApplication
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
/**
* 排除特定的自动配置类,使其永远不会应用。* @return the classes to exclude
*/
Class<?>[] exclude() default {};
/**
* 排除特定的自动配置类名称,使它们永远不会
* 适用。* @return the class names to exclude
* @since 1.3.0
*/
String[] excludeName() default {};}
/**
* 如果有此注解将会注册到 spring ioc 容器中
* {@link AutoConfigurationPackages}.
*
* @author Phillip Webb
* @since 1.3.0
* @see AutoConfigurationPackages
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
}
2.AutoConfigurationImportSelector
实现 DeferredImportSelector、BeanClassLoaderAware、ResourceLoaderAware、BeanFactoryAware、EnvironmentAware、Ordered 接口,处理 @EnableAutoConfiguration
注解的资源导入。
2.1 getCandidateConfigurations
// AutoConfigurationImportSelector.java
/**
* 返回应考虑的自动配置类名称。默认
* 此方法将使用 {@link SpringFactoriesLoader} 与
* {@link #getSpringFactoriesLoaderFactoryClass()}.
* @param metadata the source metadata
* @param attributes the {@link #getAttributes(AnnotationMetadata) annotation
* attributes}
* @return a list of candidate configurations
*/
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
// <1> 加载指定类型 EnableAutoConfiguration 对应的,在 `META-INF/spring.factories` 里的类名集合
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;
}
这里可以结合源码 debug 试试就知道了,加载的都是如下的配置