Spring Boot源码阅读

 

目录

基本问题

拓展问题

基本问题解答

拓展问题解答


基本问题

  1. 配置文件加载的时机
  2. 启动类添加到容器中的时机
  3. 其他的bean添加到容器中的时机
  4. tomcat的启动时机
  5. 加在启动类上的注解生效的时机
  6. mapper bean生成的时机
  7. Controller与Tomcat关联的时机

拓展问题

  1. 如果有多个Configuration类是怎么处理的

基本问题解答

1. Spring Boot将调用它的启动类显示的load到容器里

2. prepareContext方法中由beanFactory中的ConfigurationClassPostProcessor对容器中的bean做处理,此时容器中仅有一些预先注册的处理器以及启动类

3. 接下来refreshContext方法中ConfigurationClassParse会对容器中的Configuration做处理,启动类上因为有Configuration注解而被当做Configuration处理,parse的逻辑是读取Configuration上的ComponentScans和ComponentScan注解,拿到注解中配置的basePackages,如果basePackages为空,那就用启动类的文件夹路径作为basePackages,然后扫描该路径下的所有Component(会扫描所有文件,过滤掉不是Component的,所以basePackages配置成controller的路径应该会更快),此时,被直接扫描到的bean就注册到容器中了,但这时候bean之间的依赖仍然没有遍历

4. @EnableAutoConfiguration注解中有@Import(AutoConfigurationImportSelector.class),在parse完Configuration后立刻调用processDeferredImportSelectors处理Selector,最终会调到AutoConfigurationImportSelector中的selectImports方法,这也是一个扩展点,在该方法中会读取classpath下所有的META-INF/spring-autoconfigure-metadata.properties,该文件中配置了许多Configuration,这些Configuration都会处理并生效,内嵌的Tomcat的Confguration也是从这个配置加载的(org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration),从这个Configuration中会注册一个Tomcat的Factory到容器中,随后在context执行onRefresh时会显示创建webServer,里面的逻辑则是从容器中拿到这个factory,创建出tomcat

5. parse完并处理完ImportSelector后会由ConfigurationClassBeanDefinitionReader对之前所有加载的Configurations执行loadBeanDefinitions,这个方法主要是注册Configuration相关的bean,这些bean有通过注解Import Configuration导入的,有注解ImportBeanDefinitionRegistrar导入的。举个例子,@EnableFeignClients注解里面是@Import(FeignClientsRegistrar.class),这时候就会调用FeignClientsRegistrar这个类的方法来导入feign相关的bean,所以这其实是Spring boot给出来的一个扩展点

拓展问题解答

1. parse完Configuration后就拿到了相关联的bean,随之就会对这些bean做检查,如果该bean是Configuration,则继续递归parse

草稿

Configuration上可以使用条件过滤器

@ConditionalOnClass(HikariDataSource.class)
    @ConditionalOnMissingBean(DataSource.class)
    @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource", matchIfMissing = true)

@ConditionalOnClass这个可以在对Configuration处理时最先过滤掉,因为这个只需要判断类存不存在就行了

@ConditionalOnProperty这个也可以比较早的处理掉,在配置文件解析完就可以判断了

@ConditionalOnMissingBean这个得最后才能处理,因为要判断bean是不是存在,必须等所有Configuration类解析完,并把所有相关bean都load到容器中才能判断

猜你喜欢

转载自blog.csdn.net/xiaocszn/article/details/86522140