开发者

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

目录
  • 启动原理
  • SpringApplication
    • 1、初始化
    • 2、调用run方法
  • 自动配置原理

    放本地文件夹都快吃土了,准备清理文件夹,关于Springboot的!

    启动原理

    @SpringBootApplication
    public class Start {
    
        public static void main(String[] args) {
            SpringApplication.run(Start.class, args);
        }
    
    }

    SpringApplication

    1、初始化

    public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
            return (new SpringApplication(primarySources)).run(args);
        }
     public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
            this.sources = new LinkedHashSet(); // 
            this.bannerMode = Mode.CONSOLE;// 控制banner
            this.logStartupInfo = true;// 是否启动日志
            this.addCommandLineProperties = true; // 读取命令行配置
            this.addConversionService = true; //添加转换器
            this.headless = true; // 
            this.registerShutdownHook = true; // 注册重启
            this.additionalProfiles = Collections.emptySet();// 读取配置环境
            this.isCustomEnvironment = false;// 是否是自定义环境
            this.lazyInitialization = false; // 是否懒加载
            this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
            this.applicationStartup = ApplicationStartup.DEFAULT; // ApplicationStartup DEFAULT = new DefaultApplicationStartup();
            this.resourceLoader = resourceLoader;// 资源加载器
            Assert.notNull(primarySources, "PrimarySources must not be null");
            this.primarySources = new LinkedHashSet(Arrays.asList(primarySources)); // 主程序
            this.webApplicationType = WebApplicationType.deduceFromClasspath();//  SERVLET||REACTIVE; 是servlet还是reactive环境
            // BootstrapRegistryInitializer
    	this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
            // ApplicationContextInitializer
    	this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
    	// ApplicationListener        
    	this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
            this.mainApplicationClass = this.deduceMainApplicationClass();
        }

    注册 BootstrapRegistryInitializer

    this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
    
    // 
    private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
            ClassLoader classLoader = this.getClassLoader();
            // 1、从配置文件读取名称加载
            Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
            // 2、获取构造器实例
     	List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
            // 3、排序
    	 AnnotationAwareOrderComparator.sort(instances);
            return instances;
    }
    
    // 1、加载配置
     private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
            Map<String, List<String>> result = (Map)cache.get(classLoader);
            if (result != null) {
                return result;
            } else {
                HashMap result = new HashMap();
    
                try {
                     //核心 从这里知道读http://www.devze.com取配置文件位置 默认
                    Enumeration urls = classLoader.getResources("META-INF/spring.factories");
    		// ... 这里省略迭代器遍历注册
                    result.replaceAll((factoryType, implementations) -> {
                        return (List)implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
                    });
    		// 添加到缓存中,下次读取。根据类名读取
                    cache.put(classLoader, result);
                    return result;
                } catch (IOException var14) {
                    throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var14);
                }
            }
        }
    
    // 2、获取构造器实例
    private <T> List<T> createSpringFactoriesInsBhwyQtances(Class<T> type, Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args, Set<String> names) {
            List<T> instances = new ArrayList(names.size());
            Iterator var7 = names.iterator();
    
            while(var7.hasNext()) {
                String name = (String)var7.next();
    
                try {
                    // 通过类名反射机制调用,读取Class<T> class
                    Class<?> instanceClass = ClassUtils.forName(name, classLoader);
                    Assert.isAssignable(type, instanceClass);
                    Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
                    // 获取构造器实例
     		T instance = BeanUtils.instantiateClass(constructor, args);
                    // 添加到构造器中
                    instances.add(instance);
                } catch (Throwable var12) {
                    throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, var12);
                }
            }
    	// 返回
            return instances;
        }
    
    
    // 排序 通过debug这里调用的是Integer类型排序方法 List<Integer> list
      public static void sort(List<?> list) {
            if (list.size() > 1) {
                list.sort(INSTANCE);
            }
    
        }
    

    配置文件

    spring-boot:2.7.1.META-INF\spring.factorie

    org.springframework.context.ApplicationContextInitializer=\
    org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
    org.springframework.boot.context.ContextIdApplicationContextInitializer,\
    org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
    org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\
    org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

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

    像 BootstrapRegistryInitializer

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

    例如

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

    注册 ApplicationContextInitializer 、ApplicationListener

    同 BootstrapRegistryInitializer加载原理

    2、调用run方法

    核心

    public ConfigurableApplicationContext run(String... args) {
            long startTime = System.nanjsoTime();
            DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
            ConfigurableApplicationContext context = null;
            this.configureHeadlessProperty();
            SpringApplicationRunListeners listeners = this.getRunListeners(args);
            listeners.starting(bootstrapContext, this.mainApplicationClass);
    
            try {
                ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
                ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
                this.configureIgnoreBeanInfo(environment);
                Banner printedBanner = this.printBanner(environment);
                context = this.createApplicationContext();
                context.setApplicationStartup(this.applicationStartup);
                this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
                // 加载所有注解使用的扫描的组件
    	    this.refreshContext(context);
    	    // 刷新
                this.afterRefresh(context, applicationArguments);
                Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
                if (this.logStartupInfo) {
                    (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), timeTakenToStartup);
                }
    
                listeners.started(context, timeTakenToStartup);
                this.callRunners(context, applicationArguments);
            } catch (Throwable var12) {
                this.handleRunFailure(context, var12, listeners);
                throw new IllegalStateException(var12);
            }
    
            try {
                Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
                listeners.ready(context, timeTakenToReady);
                return context;
            } catch (Throwable var11) {
                this.handleRunFailure(context, var11, (SpringApplicationRunListeners)null);
                throw new IllegalStateException(var11);
            }
        }
    

    所有组件经过org.springframework.context.annotatiwww.devze.comon.ConfigurationClassBeanDefinitionReader方法加载注册组件

    private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {
            AnnotationMetadata metadata = configClass.getMetadata();
            AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);
            ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);
            configBeanDef.setScope(scopeMetadata.getScopeName());
            String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
            AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);
            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
            definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
            // 在这里注册
    	this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());
            configClass.setBeanName(configBeanName);
            if (logger.isTraceEnabled()) {
                logger.trace("Registered bean definition for imported class '" + configBeanName + "'");
            }
    
        }

    org.springframework.beans.factory.support.DefaultListableBeanFactory

    • registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition())
    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
    			throws BeanDefinitionStoreException {
    
    		Assert.hasText(beanName, "Bean name must not be empty");
    		Assert.notNull(beanDefinition, "BeanDefinition must not be null");
    
    		if (beanDefinition instanceof AbstractBeanDefinition) {
    			try {
    				((AbstractBeanDefinition) beanDefinition).validate();
    			}
    			catch (BeanDefinitionValidationException ex) {
    				javascriptthrow new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
    						"Validation of bean definition failed", ex);
    			}
    		}
    
    		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    		if (existingDefinition != null) {
    			if (!isAllowBeanDefinitionOverriding()) {
    				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
    			}
    			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
    				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
    				if (logger.isInfoEnabled()) {
    					logger.info("Overriding user-defined bean definition for bean '" + beanName +
    							"' with a framework-generated bean definition: replacing [" +
    							existingDefinition + "] with [" + beanDefinition + "]");
    				}
    			}
    			else if (!beanDefinition.equals(existingDefinition)) {
    				if (logger.isDebugEnabled()) {
    					logger.debug("Overriding bean definition for bean '" + beanName +
    							"' with a different definition: replacing [" + existingDefinition +
    							"] with [" + beanDefinition + "]");
    				}
    			}
    			else {
    				if (logger.isTraceEnabled()) {
    					logger.trace("Overriding bean definition for bean '" 开发者_Python入门+ beanName +
    							"' with an equivalent definition: replacing [" + existingDefinition +
    							"] with [" + beanDefinition + "]");
    				}
    			}
    			// 注册
    			this.beanDefinitionMap.put(beanName, beanDefinition);
    		}
    		else {
    			if (hasBeanCreationStarted()) {
    				// Cannot modify startup-time collection elements anymore (for stable iteration)
    				synchronized (this.beanDefinitionMap) {
    					this.beanDefinitionMap.put(beanName, beanDefinition);
    					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
    					updatedDefinitions.addAll(this.beanDefinitionNames);
    					updatedDefinitions.add(beanName);
    					this.beanDefinitionNames = updatedDefinitions;
    					removeManualSingletonName(beanName);
    				}
    			}
    			else {
    				// Still in startup registration phase
    				this.beanDefinitionMap.put(beanName, beanDefinition);
    				this.beanDefinitionNames.add(beanName);
    				removeManualSingletonName(beanName);
    			}
    			this.frozenBeanDefinitionNames = null;
    		}
    
    		if (existingDefinition != null || containsSingleton(beanName)) {
    			resetBeanDefinition(beanName);
    		}
    		else if (isConfigurationFrozen()) {
    			clearByTypeCache();
    		}
    	}
    

    自动配置原理

    该部分暂时找不到了,之前备份找不到了,先TODO下吧!喜欢的朋友参考下这篇文章:https://www.jb51.net/article/266763.htm

    到此这篇关于Springboot启动原理和自动配置原理解析的文章就介绍到这了,更多相关Springboot启动原理和自动配置内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜