介绍
启用 Spring 应用程序上下文的自动配置,尝试猜测并配置您可能需要的bean。自动配置类通常根据您的 classpath 和您已经定义的bean来实现。例如,如果您的 classpath 中有 tomcat-embedded.jar,则可能需要一个TomcatEmbeddedServletContainerFactory(除非您已经定义了自己的 EmbeddedServletContainerFactory bean)。
自动配置尝试尽可能的智能化,并在当您定义更多的自己的配置时回退。您可以随时手动 exclude()
任何您不想应用的配置(如果您不能访问他们,请使用 excludeName()
)。您也可以通过 spring.autoconfigure.exclude
属性排除它们。自动配置总是在用户定义的 bean 注册之后实施。
用 @EnableAutoConfiguration
注解的类的 package 具有特定的意义,通常用作“默认”。例如,它将在扫描 @Entity
类时使用。通常建议您将 @EnableAutoConfiguration
放在 root package 中,以便可以搜索所有子 package 和类。
自动配置类是常规的 Spring 配置bean。它们使用 SpringFactoriesLoader
机制(以类作为Key)进行查找。通常,自动配置 bean 是 @Conditional
bean(通常使用 @ConditionalOnClass
和 @ConditionalOnMissingBean
注解)。
代码实现
annotation 定义
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}
- Target: TYPE,用于类
- Retention: RUNTIME,编译和运行时可见
- Documented: 有文档要求
- Inherited: 可以继承
- AutoConfigurationPackage:表示包含这个注解的 package 应该被注册到
AutoConfigurationPackages
annotation import
import 了 EnableAutoConfigurationImportSelector:
......
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}
EnableAutoConfigurationImportSelector 中定义了一个 isEnabled() 方法:
@Override
protected boolean isEnabled(AnnotationMetadata metadata) {
if (getClass().equals(EnableAutoConfigurationImportSelector.class)) {
return getEnvironment().getProperty(
EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class,
true);
}
return true;
}
ENABLED_OVERRIDE_PROPERTY 配置项可以用来覆盖配置来开启/关闭自动配置的功能。
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
}
annotation 内容
如果希望排除某些不想自动配置的内容,可以使用 exclude() 和 excludeName() 方法:
public @interface EnableAutoConfiguration {
/**
* 排除特定的自动配置类,使其不会被应用。
* @return the classes to exclude
*/
Class<?>[] exclude() default {};
/**
* 排除特定的自动配置类名,使其永远不会被应用。
* @return the class names to exclude
* @since 1.3.0
*/
String[] excludeName() default {};
}