springboot中怎么配置AutoConfiguration
这期内容当中小编将会给大家带来有关springboot中怎么配置AutoConfiguration,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
成都创新互联是专业的临城网站建设公司,临城接单;提供成都网站制作、网站设计,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行临城网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
1.如何开启自动配置
在启动类上增加注解@EnableAutoConfiguration或者@SpringBootApplication,注意:如果使用@SpringBootApplication同时会默认开启@ComponentScan。
2.@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 引入了 1)@AutoConfigurationPackage注解 2)AutoConfigurationImportSelector.class
我们先看看AutoConfigurationImportSelector.class类的实现,@AutoConfigurationPackage注解稍后再解读。
3.AutoConfigurationImportSelector.class类实现
AutoConfigurationImportSelector是继承的DeferredImportSelector,并且使用@Import注解导入的(具体可以查看springboot之@Import注解)。所以,我们主要看 selectImports 方法的实现。
@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { //判断是否开启自动配置,默认开启,可以使用spring.boot.enableautoconfiguration=false关闭自动配置 return NO_IMPORTS; } AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata); return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}
从源码可以看出,先检查了一下是否开启自动配置,然后获取所有自动配置的类路径,并返回。进一步查看getAutoConfigurationEntry方法。
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { //1)再次判断是否开启自动配置 return EMPTY_ENTRY; } AnnotationAttributes attributes = getAttributes(annotationMetadata); //2)获取注解信息 Listconfigurations = getCandidateConfigurations(annotationMetadata, attributes); //3)获取所有自动配置的类 configurations = removeDuplicates(configurations); Set exclusions = getExclusions(annotationMetadata, attributes); //4)获取需要排除掉的自动配置类 checkExcludedClasses(configurations, exclusions); //5)校验需要排除的类是否存在,如果不存在,抛出异常 configurations.removeAll(exclusions); //6)过滤掉需要排除的类 configurations = getConfigurationClassFilter().filter(configurations); //7)通过配置的filter过滤掉需要排除的类 fireAutoConfigurationImportEvents(configurations, exclusions); //8) 通知自动配置listener,AutoConfigurationImportListener return new AutoConfigurationEntry(configurations, exclusions); //9)返回最终需要自动配置的类}
主要看一下getCandidateConfigurations方法实现:
protected ListgetCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); //使用spring通用工厂加载 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;}
最终返回给DeferredImportSelector的自动配置类列表,是通过SpringFactoriesLoader通用工厂加载的,SpringFactoriesLoader会扫描classpath下的所有 META-INF/spring.factories 文件,并通过key-value键值对的方式获取配置。而我们autoconfig功能使用的key=org.springframework.boot.autoconfigure.EnableAutoConfiguration。如下图:
所以,如果我们自己需要实现autoconfig,只需要在classpath路径下新建一个文件META-INF/spring.factories,并加上org.springframework.boot.autoconfigure.EnableAutoConfiguration=实现类,即可。
4.@AutoConfigurationPackage注解
现在,回过头来,我们看下@EnableAutoConfiguration上的@AutoConfigurationPackage注解的作用。
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@Import(AutoConfigurationPackages.Registrar.class)public @interface AutoConfigurationPackage { String[] basePackages() default {}; Class[] basePackageClasses() default {};}
查看源码可以看到,@AutoConfigurationPackage注解上import了AutoConfigurationPackages.Registrar.class。
5.AutoConfigurationPackages.Registrar.class类实现
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports { @Override public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0])); // 1)初始化 PackageImports 2)注册bean } @Override public Set