Spring Boot起步依赖源码分析(二)

 2019-10-17 21:58  阅读(1120)
文章分类:Spring boot

Spring Boot起步依赖源码分析(一)
上次说到EnableAutoConfigurationImportSelector.getCandidateConfigurations方法导入了META-INF/spring.factories配置文件,把配置信息封装到了一个List集合中,接下来看下这个方法在什么地方呗调用,这里交大家一个eclipse看源码的小技巧,在方法名上右键然后选择Open Call Hierarchy就可以快速找到什么地方调用了这个方法。

@Override
        public String[] selectImports(AnnotationMetadata metadata) {
            if (!isEnabled(metadata)) {
                return NO_IMPORTS;
            }
            try {
                AnnotationAttributes attributes = getAttributes(metadata);
                List<String> configurations = getCandidateConfigurations(metadata,
                        attributes);
                configurations = removeDuplicates(configurations);
                Set<String> exclusions = getExclusions(metadata, attributes);
                configurations.removeAll(exclusions);
                configurations = sort(configurations);
                recordWithConditionEvaluationReport(configurations, exclusions);
                return configurations.toArray(new String[configurations.size()]);
            }
            catch (IOException ex) {
                throw new IllegalStateException(ex);
            }
        }

这段代码需要跟大家分析分析了
1、getAttributes(metadata);获取到了@EnableAutoConfiguration(exclude={},excludeName={})注解上的exclude和excludeName
2、

Set<String> exclusions = getExclusions(metadata, attributes);
    configurations.removeAll(exclusions);

通过这两行代码把我们不需要的自动装配的configure排除掉。接着configurations = sort(configurations);对起步依赖的启动项进行了排序,让配置项顺序注入IOC,后面做了一些记录操作,然后把处理好的配置集合装换成了String[]数组返回,为什么要转成数组呢?如果你有这个疑问,那么恭喜你,你又get到一项新技能,因为到这里配置文件已经彻底初始化完毕,后面对这个配置集合的操作,不会再有插入和删除,只会有迭代和随机插叙,而数组进行随机访问和迭代操作的速度是最快的。
获取到配置信息之后,spring boot会加载配置信息中的所有配置类,这里我们从配置信息中取一个比较熟悉的org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,源码如下:

@Configuration
    @ConditionalOnWebApplication
    @ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
            WebMvcConfigurerAdapter.class })
    @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
    @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
    @AutoConfigureAfter(DispatcherServletAutoConfiguration.class)
    public class WebMvcAutoConfiguration {

        //......代码略

    }

看到这,如果你熟悉spring4.x的条件注解的话,上面的代码应该就很情切了,这里还是简单提一下@Conditional根据满足某一个条件创建一个特定的Bean。比如说当一个jar包在一个类路径下时,自动配置一个或多个Bean,或者只有某个Bean被创建时才会创建另一个Bean。Spring Boot中将大量使用到进行一些自动配置。举个例子比如:

@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,WebMvcConfigurerAdapter.class })

当我们的Jar依赖也就是有我们的环境中存在Servlet.class, DispatcherServlet.class,WebMvcConfigurerAdapter.class这几个类文件,即条件满足。
到这里,你应该就明白了,spring boot 高大上的自动配置起步依赖是怎么玩起来的,我们再来总结一下
1、spring boot启动时回去导入spring-boot-autoconfigure包下META-INF/spring.factories配置文件
2、根据XxxxAutoConfiguration配置类的条件注解@Conditional判断当前环境中是否满足XxxxAutoConfiguration的注解条件,如果满足,则自动向spring ioc 容器中注入bean


来源:[]()

点赞(0)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> Spring Boot起步依赖源码分析(二)

相关推荐