springboot的@EnableAutoConfiguration起作用的原理
Posted swave
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot的@EnableAutoConfiguration起作用的原理相关的知识,希望对你有一定的参考价值。
通常我们启动一个springboot项目会在启动方法中增加@SpringBootApplicatoin注解,该注解中包含了@EnableAutoConfiguration
@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) 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) 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. * <p> * 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 ;
那么@EnableAutoConfiguration是如何自动起作用的呢。我们先来看看@EnableAutoConfiguration的定义
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(AutoConfigurationImportSelector.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 ;
我们看看EnableAutoConfiguration的注释定义:
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.
大概的意思是:容器尝试猜测你想配置的bean,然后自动加载。
很欣喜的发现了@EnableAutoConfiguration里面引用了@Import(AutoConfigurationImportSelector.class),直觉看起来像这个AutoConfigurationImportSelector里面引入了我们那些自动配置(数据源、拦截器)的类。
我们来看看AutoConfigurationImportSelector的定义:
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered
原来AutoConfigurationImportSelector类实现了org.springframework.context.annotation.DeferredImportSelector
那么实现了该类的public String[] selectImports(AnnotationMetadata annotationMetadata)后,spring在解析bean的时候,就会自动调用该方法来加载拓展类,也就是selectImports方法返回的名称列表来加载类。
很容易起想到selectImports里面就返回了AutoEnableConfiguration的那些数据源、拦截器配置的类。!
接下来看看selectImports的具体实现:
以上是关于springboot的@EnableAutoConfiguration起作用的原理的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot 高级 原理分析 -- @Import注解
SpringBoot 高级 原理分析 -- @Enable*注解@Import注解
Spring构建Springboot项目 实现restful风格接口