spring boot 自動設定解密之註解@EnableAutoConfiguration spring boot為了自動設定,增加了註解@EnableAutoConfiguration,spring boot 1.2版之前, 我們的啟動類需要加註解:
@Configuration @EnableAutoConfiguration @ComponentScan
spring boot 1.2版之後新增了註解@SpringBootApplication,上面的註解就可以用一個註解替換:
@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 { 註解 @EnableAutoConfiguration是spring boot自動設定的關鍵, 也是擴充spring boot的關鍵之處。 spring boot試圖根據條件來註冊我們需要的bean執行個體: 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 tomcat-embedded.jar on your classpath you are likely to want a TomcatServletWebServerFactory (unless you have defined your own ServletWebServerFactory bean). When using SpringBootApplication, the auto-configuration of the context is automatically enabled and adding this annotation has therefore no additional effect.
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 exclude() any configuration that you never want to apply (use excludeName() if you don't have access to them). You can also exclude them via the 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 @EnableAutoConfiguration, usually via @SpringBootApplication, has specific significance and is often used as a 'default'. For example, it will be used when scanning for @Entity classes. It is generally recommended that you place @EnableAutoConfiguration (if you're not using @SpringBootApplication) in a root package so that all sub-packages and classes can be searched. Auto-configuration classes are regular Spring Configuration beans. They are located using the SpringFactoriesLoader mechanism (keyed against this class). Generally auto-configuration beans are @Conditional beans (most often using @ConditionalOnClass and @ConditionalOnMissingBean annotations).
註解@EnableAutoConfiguration之所以能自動自動設定bean,主要是其註解 @Import(AutoConfigurationImportSelector.class)中的類org.springframework.boot.autoconfigure .AutoConfigurationImportSelector起主要作用,它主要尋找必要的一些配置類。 AutoConfigurationImportSelector類有幾個方法,但對於spring boot 能自動設定的關鍵方法是:
/** * 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 List<String> getCandidateConfigurations(AnnotationMetadata metadata,AnnotationAttributes attributes) {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;} 該方法返回
spring boot約定需要自動設定的類。
代碼:
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
主要功能是從檔案
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
擷取
約定好的自動設定類。spring boot預設提供的自動設定類路徑:
spring-boot-autoconfigure-2.0.0.M7.jar!/META-INF/spring.factories 比如一個自動設定類:
@Configuration@ConditionalOnWebApplication(type = Type.SERVLET)@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,ValidationAutoConfiguration.class })public class WebMvcAutoConfiguration {public static final String DEFAULT_PREFIX = "";public static final String DEFAULT_SUFFIX = "";private static final String[] SERVLET_LOCATIONS = { "/" };@Bean@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {return new OrderedHiddenHttpMethodFilter();}......} 這個自動設定類是不是要執行個體化及內部配置的bean是不是需要執行個體化,這又回到了 博文 http://blog.csdn.net/doctor_who2004/article/details/79184230 講的註解 @Conditional的作用了。 有興趣的可以查看spring boot相關源碼。