springboot自动配置原理

最好自己跟着源码看,懒得看的可以直接看后面的总结

springboot的自动配置要从我们的启动类注解@SpringBootApplication说起
进入@SpringBootApplication注解中:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

重要注解有三个

  • @SpringBootConfiguration:内部就是一个@Configuration注解,就是让该类支持java类配置(用java类配置代替xml配置形式)
  • @ComponentScan:就是注解扫描,默认扫描当前类下的包,会把在@Component注解下的类的注册成bean加载到spring容器中,如@Controller、@Service、@Repository、@Configuration等注解
  • @EnableAutoConfiguration:这个就是完成我们自动配置的关键注解

进入@EnableAutoConfiguration中:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

这里有两个重要的注解@AutoConfigurationPackage@Import

1.进入@AutoConfigurationPackage中:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {

这里引入了一个AutoConfigurationPackages类的内部Registrar类,进入该类:

/**
* {@link ImportBeanDefinitionRegistrar} to store the base package from the importing
* configuration.
*/
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry)     {
        register(registry, new PackageImport(metadata).getPackageName());
    }

    @Override
    public Set<Object> determineImports(AnnotationMetadata metadata) {
        return Collections.singleton(new PackageImport(metadata));
    }
}

同时在AutoConfigurationPackages类中也有一句注释:

/**
* Class for storing auto-configuration packages for reference later (e.g. by JPA entity
* scanner).
*
* @author Phillip Webb
* @author Dave Syer
* @author Oliver Gierke
* @since 1.0.0
*/
public abstract class AutoConfigurationPackages {

意思是 这个类是用来存储自动配置的包供以后引用,简单来说就相当于@ComponentScan注解扫描。
那为什么在已有@ComponentScan的情况下还需要这个扫描呢?
注释中还有一个例子:(e.g. by JPA entity scanner).就是如果使用了Spring Data JPA那么在实体类上的@Entity就会使用这个
@AutoConfigurationPackage注解来进行扫描,所以这两个注解扫描的对象不同。

2.进入@Import(AutoConfigurationImportSelector.class)引入的类中:
在这里插入图片描述
进入该getAutoConfigurationEntry()方法:在这里插入图片描述
继续进入getCandidateConfigurations()方法:
在这里插入图片描述
进入loadFactoryNames()方法:
在这里插入图片描述
那么key值factoryClassName是什么呢?
就是loadFactoryNames()方法的第一个参数getSpringFactoriesLoaderFactoryClass()方法的返回值的getName()值:
在这里插入图片描述
所以key值为EnableAutoConfiguration
那么value呢?
value值就是从jar包中的META-INF/spring.factories文件中加载:
在这里插入图片描述
spring.factories文件:
在这里插入图片描述

总结

  1. @SpringBootApplication注解中包含了@EnableAutoConfiguration注解,该注解中引入了一个AutoConfigurationImportSelector类,
  2. AutoConfigurationImportSelector类会去META-INF/spring.factories文件内将里面的内容封装在Map<String, List<String>>格式的集合中,
  3. 然后取出key为EnableAutoConfiguration的value值,
  4. 这个value值内就是自动配置信息,即自动配置类的全路径,自动配置类其实就是加了@Configuration和@Bean的配置类,用这个配置类代替了原本的xml配置,并且这些配置类都进行了默认配置,即"约定大于配置"
  5. 有了自动配置类的全路径,spring就会找到这些配置类并加载到IOC容器中使配置生效。

所以整个过程就是各种spring-boot-stater的依赖,它们的jar包内提供好了自动配置类(使用java配置类的方式替代了xml配置),

但是springboot并不知道这些配置类的位置,也就无法将它们加载到IOC容器中让它们的配置生效。

所以每次加入spring-boot-stater的依赖就会将它们配置类的路径记录在spring.factories文件中,springboot需要做的就是去spring.factories文件中拿到这些配置类的路径,并根据路径找到配置类将它们加载进入IOC容器中,让它们的默认配置生效。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值