> 资讯 >

世界讯息:Springboot启动原理和自动配置原理解析

时间:2023-04-26 06:10:11       来源:脚本之家
目录
启动原理SpringApplication1、初始化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  Collection getSpringFactoriesInstances(Class type, Class[] parameterTypes, Object... args) {
        ClassLoader classLoader = this.getClassLoader();
        // 1、从配置文件读取名称加载
        Set names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
        // 2、获取构造器实例
 	List instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
        // 3、排序
	 AnnotationAwareOrderComparator.sort(instances);
        return instances;
}

// 1、加载配置
 private static Map> loadSpringFactories(ClassLoader classLoader) {
        Map> result = (Map)cache.get(classLoader);
        if (result != null) {
            return result;
        } else {
            HashMap result = new HashMap();

            try {
                 //核心 从这里知道读取配置文件位置 默认
                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  List createSpringFactoriesInstances(Class type, Class[] parameterTypes, ClassLoader classLoader, Object[] args, Set names) {
        List instances = new ArrayList(names.size());
        Iterator var7 = names.iterator();

        while(var7.hasNext()) {
            String name = (String)var7.next();

            try {
                // 通过类名反射机制调用,读取Class 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 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

像 BootstrapRegistryInitializer

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

例如

注册 ApplicationContextInitializer 、ApplicationListener

BootstrapRegistryInitializer加载原理

2、调用run方法

核心

public ConfigurableApplicationContext run(String... args) {
        long startTime = System.nanoTime();
        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.annotation.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) {
				throw 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 "" + 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 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启动原理和自动配置内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家

标签:

消息推送