springboot的自动配置原理

论坛 期权论坛 脚本     
匿名技术用户   2021-1-5 05:34   11   0

1、自动配置类源码:在spring-boot-autoconfigure-x.x.x.x.jar中

2、以启动类的@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 {
     
     //代码省略
}

进入@EnableAutoConfiguration(开启自动配置),看看是怎么进行自动配置的.

下面源码可以看到,最主要的是这里会使用@Import注解导入一个类AutoConfigurationImportSelector。下面我们进入这个类看看大概怎么实现的

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})  //导入AutoConfigurationImportSelector类
public @interface EnableAutoConfiguration {
    
      //代码省略.....
}

进入AutoConfigurationImportSelector类:在该类中我们只需要观察selectImports方法的实现。

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
    //省略代码


    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }

  //省略代码

}

该selectImports调用了loadMetadata静态方法。该静态方法会扫描所有具有META-INF/spring.factories的jar包。spring-boot-autoconfigure-x.x.x.x.jar里就有一个这样的spring.factories文件。

 static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader) {
        return loadMetadata(classLoader, "META-INF/spring-autoconfigure-metadata.properties");
    }

这个时候我们回到spring-boot-autoconfigure-x.x.x.x.jar下看看这个文件大概是什么?

可以从下图发现这个spring.factories文件也是一组一组的key=value的形式,其中一个key是EnableAutoConfiguration类的全类名,而它的value是一个xxxxAutoConfiguration的类名的列表,这些类名以逗号分隔,如下图所示:

我们可以看见一些rabbitmq、springbatch的一些对应的配置类。这些配置类都配置了默认的属性信息值(我们也可以在springboot的配置文件中配置,该类就会加载我们配置的信息)。

最后这些配置类都会被注入到spring容器中。

总结:这个@EnableAutoConfiguration注解通过@SpringBootApplication被间接的标记在了Spring Boot的启动类上。在SpringApplication.run(...)的内部就会执行selectImports()方法,找到所有JavaConfig自动配置类的全限定名对应的class,然后将所有自动配置类加载到Spring容器中。

面试总结:

参考:https://blog.csdn.net/u014745069/article/details/83820511

Spring Boot启动的时候会通过@EnableAutoConfiguration注解找到META-INF/spring.factories配置文件中的所有自动配置类,并对其进行加载,而这些自动配置类都是以AutoConfiguration结尾来命名的,它实际上就是一个JavaConfig形式的Spring容器配置类,它能通过以Properties结尾命名的类中取得在全局配置文件中配置的属性如:server.port,而XxxxProperties类是通过@ConfigurationProperties注解与全局配置文件中对应的属性进行绑定的。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP