赞
踩
springboot自动配置可以使我们省去很多编码工作,往往只需要引入一个包,所有需要的bean及配置就自动处理好了,那么springboot是如何实现自动配置的,我们又如何利用自动配置来为我们工作,本文就做一个探讨。
springboot自动配置的原理其实是在@EnableAutoConfiguration这个注解,一般我们使用springboot时都会使用@SpringBootApplication,其实这个注解已经包含了@EnableAutoConfiguration,所以用@SpringBootApplication也能开启自动配置。
我们看下@EnableAutoConfiguration这个注解。
这个注释的核心在@Import(AutoConfigurationImportSelector.class),而AutoConfigurationImportSelector是实现了DeferredImportSelector,DeferredImportSelector继承了ImportSelector,至于@Import是如何发挥作用的,我们后面再说,这里只需要知道,@Import中如果传入的是一个ImportSelector的实现类,springboot就会自动调用这个实现类的selectImports方法,这个方法返回一个String数组,数组中是class类名,springboot会根据这些class类名生成单例bean注册到容器中。
下面是selectImports的方法签名
根据上面的分析,下面的关键就是看下AutoConfigurationImportSelector这个类具体导入了哪些classes,以下是AutoConfigurationImportSelector的selectImports方法。
- @Override
- public String[] selectImports(AnnotationMetadata annotationMetadata) {
- if (!isEnabled(annotationMetadata)) {
- return NO_IMPORTS;
- }
- AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
- return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
- }
上面方法的核心是调用getAutoConfigurationEntry,而getAutoConfigurationEntry又会调用getCandidateConfigurations,这里的调用链还是挺长的,可以去看下源码,最终会调用到这个方法loadSpringFactories,这个方法就会读取META-INF/spring.factories文件,读取并解析这个文件后,会把这个文件中key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的所有类加载进来,而key org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的value值通常都是一些@Configuration标注的配置类,这样在配置类中定义的一些配置就能生效了。
spring-boot-autoconfigure包中的spring.factories文件,其中org.springframework.boot.autoconfigure.EnableAutoConfiguration这个key对应的部分value值如下:
如果我们是给别人提供服务使用,我们需要把一些bean注册到spring容器中,我们可以定义自己的@Configurations配置类,然后配置好我们的服务让别人使用,但是我们的配置类不一定能在启动时被springboot扫描到,因为用户使用springboot时一般只会配置成扫描用户自己的包,我们可以仿照上面的方式把我们配置类放到spring.factores中,这样springboot就可以自动加载我们的配置类了。
上面@Import在导入类时,如果是ImportSelector接口的实现类,会自动执行selectImports方法,这里是如何实现的呢,我们可以来分析下。
@Import起作用其实是靠spring的PostProcessor来处理的,这里用到的是
org.springframework.context.annotation.ConfigurationClassPostProcessor这个后处理器,最终处理@Import是这个方法org.springframework.context.annotation.ConfigurationClassParser#processImports,这方法中有如下判断,可以看到,如果import的是ImportSelector类型,就会调用selectImports获取要导入的类。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。