springboot自动配置原理

springboot自动配置可以使我们省去很多编码工作,往往只需要引入一个包,所有需要的bean及配置就自动处理好了,那么springboot是如何实现自动配置的,我们又如何利用自动配置来为我们工作,本文就做一个探讨。

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是如何起作用的

上面@Import在导入类时,如果是ImportSelector接口的实现类,会自动执行selectImports方法,这里是如何实现的呢,我们可以来分析下。

@Import起作用其实是靠spring的PostProcessor来处理的,这里用到的是

org.springframework.context.annotation.ConfigurationClassPostProcessor这个后处理器,最终处理@Import是这个方法org.springframework.context.annotation.ConfigurationClassParser#processImports,这方法中有如下判断,可以看到,如果import的是ImportSelector类型,就会调用selectImports获取要导入的类。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值