Springboot启动原理和自动配置原理

打印 上一主题 下一主题

主题 881|帖子 881|积分 2643

放本地文件夹都快吃土了,准备清理文件夹,关于Springboot的!
启动原理
  1. @SpringBootApplication
  2. public class Start {
  3.     public static void main(String[] args) {
  4.         SpringApplication.run(Start.class, args);
  5.     }
  6. }
复制代码
SpringApplication

1、初始化
  1. public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
  2.         return (new SpringApplication(primarySources)).run(args);
  3.     }
复制代码
  1. public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
  2.         this.sources = new LinkedHashSet(); //
  3.         this.bannerMode = Mode.CONSOLE;// 控制banner
  4.         this.logStartupInfo = true;// 是否启动日志
  5.         this.addCommandLineProperties = true; // 读取命令行配置
  6.         this.addConversionService = true; //添加转换器
  7.         this.headless = true; //
  8.         this.registerShutdownHook = true; // 注册重启
  9.         this.additionalProfiles = Collections.emptySet();// 读取配置环境
  10.         this.isCustomEnvironment = false;// 是否是自定义环境
  11.         this.lazyInitialization = false; // 是否懒加载
  12.         this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
  13.         this.applicationStartup = ApplicationStartup.DEFAULT; // ApplicationStartup DEFAULT = new DefaultApplicationStartup();
  14.         this.resourceLoader = resourceLoader;// 资源加载器
  15.         Assert.notNull(primarySources, "PrimarySources must not be null");
  16.         this.primarySources = new LinkedHashSet(Arrays.asList(primarySources)); // 主程序
  17.         this.webApplicationType = WebApplicationType.deduceFromClasspath();//  SERVLET||REACTIVE; 是servlet还是reactive环境
  18.         // BootstrapRegistryInitializer
  19.         this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
  20.         // ApplicationContextInitializer
  21.         this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
  22.         // ApplicationListener        
  23.         this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
  24.         this.mainApplicationClass = this.deduceMainApplicationClass();
  25.     }
复制代码
注册  BootstrapRegistryInitializer
  1. this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
  2. //
  3. private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
  4.         ClassLoader classLoader = this.getClassLoader();
  5.         // 1、从配置文件读取名称加载
  6.         Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
  7.         // 2、获取构造器实例
  8.         List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
  9.         // 3、排序
  10.          AnnotationAwareOrderComparator.sort(instances);
  11.         return instances;
  12. }
  13. // 1、加载配置
  14. private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
  15.         Map<String, List<String>> result = (Map)cache.get(classLoader);
  16.         if (result != null) {
  17.             return result;
  18.         } else {
  19.             HashMap result = new HashMap();
  20.             try {
  21.                  //核心 从这里知道读取配置文件位置 默认
  22.                 Enumeration urls = classLoader.getResources("META-INF/spring.factories");
  23.                 // ... 这里省略迭代器遍历注册
  24.                 result.replaceAll((factoryType, implementations) -> {
  25.                     return (List)implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
  26.                 });
  27.                 // 添加到缓存中,下次读取。根据类名读取
  28.                 cache.put(classLoader, result);
  29.                 return result;
  30.             } catch (IOException var14) {
  31.                 throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var14);
  32.             }
  33.         }
  34.     }
  35. // 2、获取构造器实例
  36. private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args, Set<String> names) {
  37.         List<T> instances = new ArrayList(names.size());
  38.         Iterator var7 = names.iterator();
  39.         while(var7.hasNext()) {
  40.             String name = (String)var7.next();
  41.             try {
  42.                 // 通过类名反射机制调用,读取Class<T> class
  43.                 Class<?> instanceClass = ClassUtils.forName(name, classLoader);
  44.                 Assert.isAssignable(type, instanceClass);
  45.                 Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
  46.                 // 获取构造器实例
  47.                 T instance = BeanUtils.instantiateClass(constructor, args);
  48.                 // 添加到构造器中
  49.                 instances.add(instance);
  50.             } catch (Throwable var12) {
  51.                 throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, var12);
  52.             }
  53.         }
  54.         // 返回
  55.         return instances;
  56.     }
  57. // 排序 通过debug这里调用的是Integer类型排序方法 List<Integer> list
  58.   public static void sort(List<?> list) {
  59.         if (list.size() > 1) {
  60.             list.sort(INSTANCE);
  61.         }
  62.     }
复制代码
配置文件
spring-boot:2.7.1.META-INF\spring.factorie
  1. org.springframework.context.ApplicationContextInitializer=\
  2. org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
  3. org.springframework.boot.context.ContextIdApplicationContextInitializer,\
  4. org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
  5. org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\
  6. org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
复制代码

像 BootstrapRegistryInitializer
另外几个配置是从其他配置文件中读取的
例如

注册 ApplicationContextInitializer 、ApplicationListener
同 BootstrapRegistryInitializer加载原理
2、调用run方法

核心
  1. public ConfigurableApplicationContext run(String... args) {
  2.         long startTime = System.nanoTime();
  3.         DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
  4.         ConfigurableApplicationContext context = null;
  5.         this.configureHeadlessProperty();
  6.         SpringApplicationRunListeners listeners = this.getRunListeners(args);
  7.         listeners.starting(bootstrapContext, this.mainApplicationClass);
  8.         try {
  9.             ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
  10.             ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
  11.             this.configureIgnoreBeanInfo(environment);
  12.             Banner printedBanner = this.printBanner(environment);
  13.             context = this.createApplicationContext();
  14.             context.setApplicationStartup(this.applicationStartup);
  15.             this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
  16.             // 加载所有注解使用的扫描的组件
  17.             this.refreshContext(context);
  18.             // 刷新
  19.             this.afterRefresh(context, applicationArguments);
  20.             Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
  21.             if (this.logStartupInfo) {
  22.                 (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), timeTakenToStartup);
  23.             }
  24.             listeners.started(context, timeTakenToStartup);
  25.             this.callRunners(context, applicationArguments);
  26.         } catch (Throwable var12) {
  27.             this.handleRunFailure(context, var12, listeners);
  28.             throw new IllegalStateException(var12);
  29.         }
  30.         try {
  31.             Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
  32.             listeners.ready(context, timeTakenToReady);
  33.             return context;
  34.         } catch (Throwable var11) {
  35.             this.handleRunFailure(context, var11, (SpringApplicationRunListeners)null);
  36.             throw new IllegalStateException(var11);
  37.         }
  38.     }
复制代码
所有组件经过org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader方法加载注册组件
  1. private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {
  2.         AnnotationMetadata metadata = configClass.getMetadata();
  3.         AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);
  4.         ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);
  5.         configBeanDef.setScope(scopeMetadata.getScopeName());
  6.         String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
  7.         AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);
  8.         BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
  9.         definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
  10.         // 在这里注册
  11.         this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());
  12.         configClass.setBeanName(configBeanName);
  13.         if (logger.isTraceEnabled()) {
  14.             logger.trace("Registered bean definition for imported class '" + configBeanName + "'");
  15.         }
  16.     }
复制代码
org.springframework.beans.factory.support.DefaultListableBeanFactory

  • registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition())
  1. @Override
  2. public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
  3.                         throws BeanDefinitionStoreException {
  4.                 Assert.hasText(beanName, "Bean name must not be empty");
  5.                 Assert.notNull(beanDefinition, "BeanDefinition must not be null");
  6.                 if (beanDefinition instanceof AbstractBeanDefinition) {
  7.                         try {
  8.                                 ((AbstractBeanDefinition) beanDefinition).validate();
  9.                         }
  10.                         catch (BeanDefinitionValidationException ex) {
  11.                                 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
  12.                                                 "Validation of bean definition failed", ex);
  13.                         }
  14.                 }
  15.                 BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
  16.                 if (existingDefinition != null) {
  17.                         if (!isAllowBeanDefinitionOverriding()) {
  18.                                 throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
  19.                         }
  20.                         else if (existingDefinition.getRole() < beanDefinition.getRole()) {
  21.                                 // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
  22.                                 if (logger.isInfoEnabled()) {
  23.                                         logger.info("Overriding user-defined bean definition for bean '" + beanName +
  24.                                                         "' with a framework-generated bean definition: replacing [" +
  25.                                                         existingDefinition + "] with [" + beanDefinition + "]");
  26.                                 }
  27.                         }
  28.                         else if (!beanDefinition.equals(existingDefinition)) {
  29.                                 if (logger.isDebugEnabled()) {
  30.                                         logger.debug("Overriding bean definition for bean '" + beanName +
  31.                                                         "' with a different definition: replacing [" + existingDefinition +
  32.                                                         "] with [" + beanDefinition + "]");
  33.                                 }
  34.                         }
  35.                         else {
  36.                                 if (logger.isTraceEnabled()) {
  37.                                         logger.trace("Overriding bean definition for bean '" + beanName +
  38.                                                         "' with an equivalent definition: replacing [" + existingDefinition +
  39.                                                         "] with [" + beanDefinition + "]");
  40.                                 }
  41.                         }
  42.                         // 注册
  43.                         this.beanDefinitionMap.put(beanName, beanDefinition);
  44.                 }
  45.                 else {
  46.                         if (hasBeanCreationStarted()) {
  47.                                 // Cannot modify startup-time collection elements anymore (for stable iteration)
  48.                                 synchronized (this.beanDefinitionMap) {
  49.                                         this.beanDefinitionMap.put(beanName, beanDefinition);
  50.                                         List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
  51.                                         updatedDefinitions.addAll(this.beanDefinitionNames);
  52.                                         updatedDefinitions.add(beanName);
  53.                                         this.beanDefinitionNames = updatedDefinitions;
  54.                                         removeManualSingletonName(beanName);
  55.                                 }
  56.                         }
  57.                         else {
  58.                                 // Still in startup registration phase
  59.                                 this.beanDefinitionMap.put(beanName, beanDefinition);
  60.                                 this.beanDefinitionNames.add(beanName);
  61.                                 removeManualSingletonName(beanName);
  62.                         }
  63.                         this.frozenBeanDefinitionNames = null;
  64.                 }
  65.                 if (existingDefinition != null || containsSingleton(beanName)) {
  66.                         resetBeanDefinition(beanName);
  67.                 }
  68.                 else if (isConfigurationFrozen()) {
  69.                         clearByTypeCache();
  70.                 }
  71.         }
复制代码
自动配置原理

该部分暂时找不到了,之前备份找不到了,先TODO下吧!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

前进之路

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表