亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解SpringBoot簡(jiǎn)化配置分析總結(jié)

 更新時(shí)間:2020年10月10日 09:21:23   作者:Theia_Suu  
這篇文章主要介紹了詳解SpringBoot簡(jiǎn)化配置分析總結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在SpringBoot啟動(dòng)類中,該主類被@SpringBootApplication所修飾,跟蹤該注解類,除元注解外,該注解類被如下自定注解修飾。

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan

讓我們簡(jiǎn)單敘述下它們各自的功能:

  • @ComponentScan:掃描需要被IoC容器管理下需要管理的Bean,默認(rèn)當(dāng)前根目錄下的
  • @EnableAutoConfiguration:裝載所有第三方的Bean
  • @SpringBootConfiguration 作用等同于@Configuration

我們來看下@SpringBootConfiguration

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
 @AliasFor(
  annotation = Configuration.class
 )
 boolean proxyBeanMethods() default true;
}

可以看到該注解類內(nèi)包含與@Configuration,其作用與@Configuration并無太大區(qū)別,只是多了層屬性嵌套。

故: @SpringBootConfiguration + @ComponentScan

將根目錄下所有被**@Controller、@Service、@Repository、@Component**等所修飾的類交給IoC容器管理。

那么重點(diǎn)來了,@EnableAutoConfiguration是如何裝載第三方Bean的呢?讓我們跟蹤下它的源碼。

首先我們可以看到該類被如下注解修飾:

@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})

我們先關(guān)注下AutoConfigurationImportSelector這個(gè)組件。

// 批量導(dǎo)入第三方的一些Bean
@Import({AutoConfigurationImportSelector.class})

其中該組件的selectImports(AnnotationMetadata annotationMetadata)方法,我們先簡(jiǎn)述下它的作用:掃描所有需要被管理的第三方Bean并交給IoC容器進(jìn)行管理。然后我們接著往下追蹤。

public String[] selectImports(AnnotationMetadata annotationMetadata) {
 if (!this.isEnabled(annotationMetadata)) {
  return NO_IMPORTS;
 } else {
  // 讓我們跟蹤到這個(gè)方法
  AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
  return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
 }
}
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
 if (!this.isEnabled(annotationMetadata)) {
  return EMPTY_ENTRY;
 } else {
  AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
  // 獲取所有AutoConfiguration的配置類
  List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
  // 下面就是對(duì)AutoConfiguration的去重、排除和過濾等操作
  configurations = this.removeDuplicates(configurations);
  Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
  this.checkExcludedClasses(configurations, exclusions);
  configurations.removeAll(exclusions);
  configurations = this.getConfigurationClassFilter().filter(configurations);
  // 我們繼續(xù)追蹤這里
  this.fireAutoConfigurationImportEvents(configurations, exclusions);
  return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
 }
}
private void fireAutoConfigurationImportEvents(List<String> configurations, Set<String> exclusions) {
 List<AutoConfigurationImportListener> listeners = this.getAutoConfigurationImportListeners();
 if (!listeners.isEmpty()) {
  // 加了層包裝
  AutoConfigurationImportEvent event = new AutoConfigurationImportEvent(this, configurations, exclusions);
  Iterator var5 = listeners.iterator();

  while(var5.hasNext()) {
   AutoConfigurationImportListener listener = (AutoConfigurationImportListener)var5.next();
   this.invokeAwareMethods(listener);
   // 向ConditionEvaluationReport中導(dǎo)入所有AutoConfiguration
   listener.onAutoConfigurationImportEvent(event);
  }
 }

}

可以猜想IoC容器在啟動(dòng)時(shí)會(huì)將這里的AutoConfiguration中的每個(gè)Bean都注入到容器中。這里的源碼我們先跟蹤到這里,大致了解了下該方法的作用。

那么SpringBoot又是如何取感知第三方的Bean文件呢?

SpringBoot和第三方Bean之間存在一定的規(guī)定。即通過對(duì)于相應(yīng)依賴的Jar包中可能存在一個(gè)spring.factories文件,在該文件中就記錄了需要被IoC容器管理的Bean文件路徑,SpringBoot通過該文件確定需要IoC管理的Bean文件位置。對(duì)于spring-boot-autoconfiguration的spring.factories文件中,記錄著大量xxxAutoConfiguration的類文件位置,這些類都被@Configuration注解標(biāo)識(shí),即這些配置類會(huì)配置多個(gè)Bean從而解決spring.factories可能產(chǎn)生的臃腫問題。

Tomcat的加載時(shí)機(jī)

對(duì)于SpringBoot來說它特點(diǎn)不僅是簡(jiǎn)化配置,還有內(nèi)嵌容器等特點(diǎn)。那么就有必要探討Tomcat容器的加載時(shí)機(jī)。在spring-boot-autoconfiguration的spring.factories文件中存在ServletWebServerFactoryAutoConfiguration配置類的路徑,該類會(huì)在項(xiàng)目啟動(dòng)時(shí)將默認(rèn)的Tomcat容器已@Bean的方式加載入IoC容器內(nèi)部。

SpringBoot是如何集中配置呢?

談?wù)撨@個(gè)問題前我們不妨先按照之前yml或properties的文件配置下

server:
 port: 8080

通過IDE,跟蹤到port所配置的成員變量所在類,發(fā)現(xiàn)該類被@ConfigurationProperties所修飾,該注解就是將yml或properties中配置按照對(duì)應(yīng)前綴注入到指定類的成員變量。該注解具體實(shí)現(xiàn)感興趣的小伙伴們可以去如下鏈接學(xué)習(xí)。   @ConfigurationProperties實(shí)現(xiàn)原理與實(shí)戰(zhàn)

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
 private Integer port;
*******
}

下面兩個(gè)代碼和前述作用大致相同

environment.getProperty("xxx");

@Value("${xxx}")

我們?cè)谑褂肧pringBoot時(shí)只需要做哪些事情?

通常我們?cè)偈褂肧pringBoot時(shí)只需要在Maven中引入類似如下的starter依賴。

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

最多再需要配置一些類似mybatis這類框架的一些屬性參數(shù)。而這些starter按照我們之前的邏輯其內(nèi)部應(yīng)該存有spring.factories文件,我們先去對(duì)應(yīng)jar包查找下。

如果有些starter的jar包沒有找到我們想要的spring.factories文件。我們可以去spring-boot-test-autoconfiguretion中的spring.factories查看下,SpringBoot內(nèi)部其實(shí)已經(jīng)定義好相當(dāng)一定數(shù)量的AutoConfiguration。

在這里插入圖片描述

果然該jar包內(nèi)確實(shí)存在spring.factories文件,代碼如下。

org.springframework.data.repository.core.support.RepositoryFactorySupport=org.springframework.data.redis.repository.support.RedisRepositoryFactory

這意味著我們已經(jīng)簡(jiǎn)單地了解了SpringBoot如何簡(jiǎn)化配置,那么我們也應(yīng)該可以自己來實(shí)現(xiàn)一個(gè)starter依賴交給SpringBoot來使用,只要在對(duì)應(yīng)Jar包中添加spring.factories文件,在其中添加如下代碼。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=xxxAutoConfiguration

大家若有時(shí)間還請(qǐng)實(shí)現(xiàn)下自己的starter依賴,對(duì)加深這部分理解還是很有幫助的。感興趣的小伙伴可以看下我做的一個(gè)簡(jiǎn)單的實(shí)現(xiàn)。 [自定義starter實(shí)現(xiàn)]

最后我們?cè)谡f下最后@SpringBootApplication中@AutoConfigurationPackage這個(gè)注解類,發(fā)現(xiàn)其中導(dǎo)入了Registrar組件。

@Import({Registrar.class})

讓我們重點(diǎn)關(guān)注registerBeanDefinitions這個(gè)方法,該方法最終會(huì)來到DefaultListableBeanFactory中registerBeanDefinition(String beanName, BeanDefinition beanDefinition)方法,將AutoConfigurationPackages.class注冊(cè)到IoC容器中,然后將主配置類所在包下所有組件導(dǎo)入到SpringIoC容器中

public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
 // 里面就這一個(gè)方法我們跟蹤下
 AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));
}
public static void register(BeanDefinitionRegistry registry, String... packageNames) {
 // 判斷beanDefinitionMap是否存在AutoConfigurationPackages
 if (registry.containsBeanDefinition(BEAN)) {
  BeanDefinition beanDefinition = registry.getBeanDefinition(BEAN);
  ConstructorArgumentValues constructorArguments = beanDefinition.getConstructorArgumentValues();
  constructorArguments.addIndexedArgumentValue(0, addBasePackages(constructorArguments, packageNames));
 } else {
  GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
  beanDefinition.setBeanClass(AutoConfigurationPackages.BasePackages.class);
  beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, packageNames);
  beanDefinition.setRole(2);
  // 將設(shè)置好的AutoConfigurationPackages注冊(cè)到beanDefinitionMap(是不是很熟悉這一步)
  registry.registerBeanDefinition(BEAN, beanDefinition);
 }

}

怎么樣,在為我們簡(jiǎn)化了配置的同時(shí),SpringBoot居然幫我們做了如此多的事情,而我們只需要簡(jiǎn)單地集中配置其中一部分的屬性。關(guān)于SpirngBoot我們就探討到這里,這些內(nèi)容是閱讀一些文章,觀看部分講解和源碼的總結(jié),若有錯(cuò)誤還請(qǐng)接納與指教。這是本人的第一篇文章,最后感謝各位的閱讀。

到此這篇關(guān)于詳解SpringBoot簡(jiǎn)化配置分析總結(jié)的文章就介紹到這了,更多相關(guān)SpringBoot 簡(jiǎn)化配置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java設(shè)置String字符串編碼方法詳解

    Java設(shè)置String字符串編碼方法詳解

    因?yàn)镾tring字符串很常用,所以我們?cè)谑褂盟倪^程中,可能會(huì)面臨各種問題,比如”中文亂碼“問題等,那么為什么中文會(huì)亂碼?本文將給大家介紹一下Java如何設(shè)置String字符串編碼,來避免和解決這一常見問題,需要的朋友可以參考下
    2023-05-05
  • SpringMVC REST風(fēng)格深入詳細(xì)講解

    SpringMVC REST風(fēng)格深入詳細(xì)講解

    這篇文章主要介紹了SpringMVC REST風(fēng)格,Rest全稱為Representational State Transfer,翻譯為表現(xiàn)形式狀態(tài)轉(zhuǎn)換,它是一種軟件架構(gòu)
    2022-10-10
  • springboot無法跳轉(zhuǎn)頁面的問題解決方案

    springboot無法跳轉(zhuǎn)頁面的問題解決方案

    這篇文章主要介紹了springboot無法跳轉(zhuǎn)頁面的問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Java批量寫入文件和下載圖片的示例代碼

    Java批量寫入文件和下載圖片的示例代碼

    這篇文章主要介紹了Java批量寫入文件和下載圖片的示例代碼,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-09-09
  • Java跨模塊調(diào)用方式

    Java跨模塊調(diào)用方式

    這篇文章主要介紹了Java跨模塊調(diào)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 詳解JAVA 弱引用

    詳解JAVA 弱引用

    這篇文章主要介紹了 JAVA 弱引用的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)java引用對(duì)象,感興趣的朋友可以了解下
    2020-08-08
  • springBoot 項(xiàng)目排除數(shù)據(jù)庫啟動(dòng)方式

    springBoot 項(xiàng)目排除數(shù)據(jù)庫啟動(dòng)方式

    這篇文章主要介紹了springBoot 項(xiàng)目排除數(shù)據(jù)庫啟動(dòng)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java中zip文件壓縮與解壓之ZipInputStream和ZipOutputStream

    Java中zip文件壓縮與解壓之ZipInputStream和ZipOutputStream

    這篇文章主要給大家介紹了關(guān)于Java中zip文件壓縮與解壓之ZipInputStream和ZipOutputStream的相關(guān)資料,ZipInputStream 和 ZipOutputStream 可以用于處理 ZIP文件格式,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • Java 8 Stream.distinct() 列表去重的操作

    Java 8 Stream.distinct() 列表去重的操作

    這篇文章主要介紹了Java 8 Stream.distinct() 列表去重的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • java之StringBuffer常見使用方法解析

    java之StringBuffer常見使用方法解析

    這篇文章主要介紹了java之StringBuffer常見使用方法解析,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11

最新評(píng)論