最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Springboot啟動(dòng)原理和自動(dòng)配置原理解析

 更新時(shí)間:2023年04月25日 14:16:21   作者:隨  
這篇文章主要介紹了Springboot啟動(dòng)原理和自動(dòng)配置原理解析,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

放本地文件夾都快吃土了,準(zhǔn)備清理文件夾,關(guān)于Springboot的!

啟動(dòng)原理

@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;// 是否啟動(dòng)日志
        this.addCommandLineProperties = true; // 讀取命令行配置
        this.addConversionService = true; //添加轉(zhuǎn)換器
        this.headless = true; // 
        this.registerShutdownHook = true; // 注冊(cè)重啟
        this.additionalProfiles = Collections.emptySet();// 讀取配置環(huán)境
        this.isCustomEnvironment = false;// 是否是自定義環(huán)境
        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環(huán)境
        // 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();
    }

注冊(cè) 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、從配置文件讀取名稱(chēng)加載
        Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
        // 2、獲取構(gòu)造器實(shí)例
 	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 {
                 //核心 從這里知道讀取配置文件位置 默認(rèn)
                Enumeration urls = classLoader.getResources("META-INF/spring.factories");
		// ... 這里省略迭代器遍歷注冊(cè)
                result.replaceAll((factoryType, implementations) -> {
                    return (List)implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
                });
		// 添加到緩存中,下次讀取。根據(jù)類(lèi)名讀取
                cache.put(classLoader, result);
                return result;
            } catch (IOException var14) {
                throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var14);
            }
        }
    }

// 2、獲取構(gòu)造器實(shí)例
private <T> List<T> createSpringFactoriesInstances(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 {
                // 通過(guò)類(lèi)名反射機(jī)制調(diào)用,讀取Class<T> class
                Class<?> instanceClass = ClassUtils.forName(name, classLoader);
                Assert.isAssignable(type, instanceClass);
                Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
                // 獲取構(gòu)造器實(shí)例
 		T instance = BeanUtils.instantiateClass(constructor, args);
                // 添加到構(gòu)造器中
                instances.add(instance);
            } catch (Throwable var12) {
                throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, var12);
            }
        }
	// 返回
        return instances;
    }


// 排序 通過(guò)debug這里調(diào)用的是Integer類(lèi)型排序方法 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

?

像 BootstrapRegistryInitializer

另外幾個(gè)配置是從其他配置文件中讀取的

例如

?

注冊(cè) ApplicationContextInitializer 、ApplicationListener

同 BootstrapRegistryInitializer加載原理

2、調(diào)用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);
        }
    }

所有組件經(jīng)過(guò)org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader方法加載注冊(cè)組件

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);
        // 在這里注冊(cè)
	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 + "]");
				}
			}
			// 注冊(cè)
			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();
		}
	}

自動(dòng)配置原理

該部分暫時(shí)找不到了,之前備份找不到了,先TODO下吧!喜歡的朋友參考下這篇文章:http://m.fzitv.net/article/266763.htm

到此這篇關(guān)于Springboot啟動(dòng)原理和自動(dòng)配置原理解析的文章就介紹到這了,更多相關(guān)Springboot啟動(dòng)原理和自動(dòng)配置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java線程池prestartCoreThread prestartAllCoreThreads的預(yù)熱源碼解讀

    java線程池prestartCoreThread prestartAllCoreThreads的預(yù)熱源碼解讀

    這篇文章主要介紹了java線程池prestartCoreThread prestartAllCoreThreads的預(yù)熱源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • Java Spring集成MapStruct詳情

    Java Spring集成MapStruct詳情

    這篇文章主要介紹了Java Spring集成MapStruct詳情,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-06-06
  • MyBatis中#和$的區(qū)別小結(jié)

    MyBatis中#和$的區(qū)別小結(jié)

    ${} 和 #{} 都是 MyBatis 中用來(lái)替換參數(shù)的,它們都可以將用戶(hù)傳遞過(guò)來(lái)的參數(shù),替換到 MyBatis 最終生成的 SQL 中,但它們區(qū)別卻是很大的,接下來(lái)我們一起來(lái)看
    2023-09-09
  • Java連接SQL?Server數(shù)據(jù)庫(kù)的超詳細(xì)教程

    Java連接SQL?Server數(shù)據(jù)庫(kù)的超詳細(xì)教程

    在Java應(yīng)用程序中我們經(jīng)常需要與數(shù)據(jù)庫(kù)進(jìn)行交互,一種常見(jiàn)的數(shù)據(jù)庫(kù)是Microsoft?SQL?Server,下面這篇文章主要給大家介紹了關(guān)于Java連接SQL?Server數(shù)據(jù)庫(kù)的超詳細(xì)教程,需要的朋友可以參考下
    2024-01-01
  • Java使用JXLS導(dǎo)出Excel詳解

    Java使用JXLS導(dǎo)出Excel詳解

    jxls是一個(gè)輕量級(jí)的Java庫(kù),用于基于模板的Excel報(bào)表生成,這篇文章主要為大家介紹了Java如何使用JXLS導(dǎo)出Excel,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-11-11
  • SpringBoot整合SpringSecurity實(shí)現(xiàn)認(rèn)證攔截的教程

    SpringBoot整合SpringSecurity實(shí)現(xiàn)認(rèn)證攔截的教程

    我們寫(xiě)的任何一個(gè)項(xiàng)目,都應(yīng)該有安全防護(hù),不應(yīng)該讓這個(gè)項(xiàng)目進(jìn)行“裸奔”,否則很容易被別人進(jìn)行攻擊。而在SpringBoot環(huán)境中,其實(shí)可以很容易實(shí)現(xiàn)安全保護(hù),本文給大家介紹SpringBoot如何整合SpringSecurity實(shí)現(xiàn)認(rèn)證攔截,需要的朋友可以參考下
    2023-05-05
  • MyBatis如何使用(二)

    MyBatis如何使用(二)

    這篇文章主要介紹了MyBatis如何使用(二)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • Spring純Java配置集成kafka代碼實(shí)例

    Spring純Java配置集成kafka代碼實(shí)例

    這篇文章主要介紹了Spring純Java配置集成kafka代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • @Configuration與@Component作為配置類(lèi)的區(qū)別詳解

    @Configuration與@Component作為配置類(lèi)的區(qū)別詳解

    這篇文章主要介紹了@Configuration與@Component作為配置類(lèi)的區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Java使用pdfbox實(shí)現(xiàn)給pdf文件加圖片水印

    Java使用pdfbox實(shí)現(xiàn)給pdf文件加圖片水印

    有時(shí)候需要給pdf加水印,市面上工具都是收費(fèi)的要會(huì)員,還是自食其力吧;嘗試過(guò) spire.pdf.free 那個(gè)超過(guò)10頁(yè)就不行了!所以本文還是使用了pdfbox,感興趣的可以了解一下
    2022-11-11

最新評(píng)論

营山县| 濮阳县| 台南县| 罗源县| 永胜县| 固原市| 苍溪县| 鹤峰县| 鹤庆县| 徐汇区| 怀来县| 南雄市| 信宜市| 清徐县| 惠来县| 鄂托克旗| 玉环县| 福海县| 凤阳县| 独山县| 获嘉县| 噶尔县| 苏尼特右旗| 武安市| 临朐县| 宝清县| 玛纳斯县| 老河口市| 大洼县| 巩义市| 宜丰县| 峡江县| 淳安县| 建德市| 仁布县| 北宁市| 图木舒克市| 延寿县| 湘潭市| 清水河县| 巢湖市|