美文网首页
2019-04-24 SpringBoot自动装配

2019-04-24 SpringBoot自动装配

作者: DoubleFooker | 来源:发表于2019-04-24 18:17 被阅读0次

    SpringBoot自动装配

    文章基于2.1.4阅读

    @SpringBootApplication

    springboot通过@SpringBootApplication注解启动,源码:

    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(excludeFilters = {
            @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
            @Filter(type = FilterType.CUSTOM,
                    classes = AutoConfigurationExcludeFilter.class) })
    public @interface SpringBootApplication {
        //...省略源码
    }
    

    从源码中可知道,@SpringbootApplication注解中实质是使用@EnableAutoConfiguration实现自动装配。
    注解@EnableAutoConfiguration,源码:

    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {
        String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
        /**
         * 通过class排除加载class
         */
        Class<?>[] exclude() default {};
        /**
         * 通过名称排除加载class
         */
        String[] excludeName() default {};
    }
    

    该注解最终实现通过检测classpath下所有META-INF/spring.factories配置文件,将其中org.springframework.boot.autoconfigure.EnableAutoConfiguration配置的class加载到spring中。

    Spring中@Import注解有三种形式注入bean。

    • 指定类的注入
    • 引入ImportSelector实现类,返回需要定义的类名数组
    • 引入ImportBeanDefinitionRegistrar实现类,在registerBeanDefinitions方法中注

    EnableAutoConfiguration注解使用第二种方法注入bean
    AutoConfigurationImportSelector,源码

    public class AutoConfigurationImportSelector
        implements 
        DeferredImportSelector, 
        BeanClassLoaderAware, 
        ResourceLoaderAware,
        BeanFactoryAware, 
        EnvironmentAware, 
        Ordered {
        //...省略源码
        @Override
        public String[] selectImports(AnnotationMetadata annotationMetadata) {
            //是否启用自动装配,否返回空数组
            if (!isEnabled(annotationMetadata)) {
                return NO_IMPORTS;
            }
            AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
                    .loadMetadata(this.beanClassLoader);
            AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
                    autoConfigurationMetadata, annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
            //获取spring.factories文件配置的类
        protected AutoConfigurationEntry getAutoConfigurationEntry(
                AutoConfigurationMetadata autoConfigurationMetadata,
                AnnotationMetadata annotationMetadata) 
        {
            //...
            AnnotationAttributes attributes = getAttributes(annotationMetadata);
            //spring.factories读取文件
            List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
              //...
            return new AutoConfigurationEntry(configurations, exclusions);
        }
            //通过SpringFactoriesLoader解析配置信息
        protected List<String> getCandidateConfigurations(
            AnnotationMetadata metadata,
            AnnotationAttributes attributes) 
        {
           //解析EnableAutoConfiguration.class配置项信息
            List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
                    getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
            return configurations;
        }
            
        //...
    }
    
    

    通过@Import引入ImporSelector形式,会根据selectImports实现的方法返回的数组定义bean。
    getSpringFactoriesLoaderFactoryClass()返回的是EnableAutoConfiguration.class全类名。
    至此@EnableAutoConfiguration通过解析spring.factories配置信息完成bean的自动装配。

    相关文章

      网友评论

          本文标题:2019-04-24 SpringBoot自动装配

          本文链接:https://www.haomeiwen.com/subject/frkngqtx.html