您好,登錄后才能下訂單哦!
不懂SpringBoot Application注解原理?其實(shí)想解決這個(gè)問題也不難,下面讓小編帶著大家一起學(xué)習(xí)怎么去分析,希望大家閱讀完這篇文章后大所收獲。
1、SpringBoot 啟動(dòng)main()
@SpringBootApplication public class TomcatdebugApplication { public static void main(String[] args) { SpringApplication.run(TomcatdebugApplication.class, args); } }
1.1 @SpringBootApplication 注解,其實(shí)主要是@ComponentScan,@EnableAutoConfiguration,@SpringBootConfiguration三個(gè)注解
@ComponentScan 注解:
spring里有四大注解:@Service,@Repository,@Component,@Controller用來定義一個(gè)bean.@ComponentScan注解就是用來自動(dòng)掃描被這些注解標(biāo)識(shí)的類,最終生成ioc容器里的bean.
可以通過設(shè)置@ComponentScan basePackages,includeFilters,excludeFilters屬性來動(dòng)態(tài)確定自動(dòng)掃描范圍,類型已經(jīng)不掃描的類型.
默認(rèn)情況下:它掃描所有類型,并且掃描范圍是@ComponentScan注解所在配置類包及子包的類
@SpringBootConfiguration 注解:
@SpringBootConfiguration繼承自@Configuration,二者功能也一致,標(biāo)注當(dāng)前類是配置類,
并會(huì)將當(dāng)前類內(nèi)聲明的一個(gè)或多個(gè)以@Bean注解標(biāo)記的方法的實(shí)例納入到spring容器中,并且實(shí)例名就是方法名。
demo 說明:
(1) 注入spring ioc bean
@SpringBootConfiguration public class Config { @Bean public Map createMap(){ Map map = new HashMap(); map.put("username","gxz"); map.put("age",27); return map; } }
(2)調(diào)用:
public static void main( String[] args ) { //方式1 獲取context ConfigurableApplicationContext context = SpringApplication.run(App.class, args); context.getBean(Runnable.class).run(); context.getBean("createMap"); //注意這里直接獲取到這個(gè)方法bean int age = (int) map.get("age"); System.out.println("age=="+age); //方式2. 使用@Autowired注解,應(yīng)用bean // @Autowired// Map createMap }
@EnableAutoConfiguration 注解
@EnableAutoConfiguration作用:從classpath中搜索所有的META-INF/spring.factories配置文件,然后將其中key為org.springframework.boot.autoconfigure.EnableAutoConfiguration的value加載到spring容器中。
上圖分析源碼可知: @EnableAutoConfiguration = @Import + @AutoConfigurationPackage
@AutoConfigurationPackage:主要作用是自動(dòng)配置包
@Import: Spring底層注解@Import,給容器中導(dǎo)入一個(gè)組件;導(dǎo)入的組件由AutoConfigurationPackages.Registrar.class將主配置類(@SpringBootApplication標(biāo)注的類)的所在包以及下面所有子包里面的所有組件掃描到Spring容器。
AutoConfigurationImportSelector的作用是導(dǎo)入哪些組件的選擇器。將所有需要導(dǎo)入的組件以全類名的方式返回,這些組件就會(huì)被添加到容器中;也會(huì)給容器導(dǎo)入非常多的自動(dòng)配置類(xxxAutoConfiguration),就是給容器中導(dǎo)入這個(gè)場(chǎng)景需要的所有組件,并配置好這些組件。
有了自動(dòng)配置類,免去了我們手動(dòng)編寫配置注入功能組件等的工作
具體工作流程圖:
@EnableAutoConfiguration加載過程
自動(dòng)配置主要由AutoConfigurationImportSelector實(shí)現(xiàn)的,我們主要從這個(gè)類開始講起。AutoConfigurationImportSelector是@EnableAutoConfiguration“@Import”的DeferredImportSelector實(shí)現(xiàn)類,由于DeferredImportSelector作為ImportSelector的子接口,所以組件自動(dòng)配置邏輯均在selectImports(AnnotationMetadata)方法中實(shí)現(xiàn)
源碼分析:
AutoConfigurationImportSelector.java
根據(jù)以上代碼分析自動(dòng)配置加載過程主要分為以下幾個(gè)步驟:
1.判斷是否開啟自動(dòng)配置
2.從META-INF/spring-autoconfigure-metadata.properties文件中載入屬性配置
3.獲取所有的配置列表
public String[] selectImports(AnnotationMetadata annotationMetadata) { //1.是否開啟自動(dòng)配置,默認(rèn)開啟 if (!this.isEnabled(annotationMetadata)) { return NO_IMPORTS; } else { try { //2.從META-INF/spring-autoconfigure-metadata.properties文件中載入屬性配置(有一些有默認(rèn)值),獲取注解信息 AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader); //3.獲取所有的配置列表 AnnotationAttributes attributes = this.getAttributes(annotationMetadata); List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes); configurations = this.removeDuplicates(configurations); configurations = this.sort(configurations, autoConfigurationMetadata); Set<String> exclusions = this.getExclusions(annotationMetadata, attributes); this.checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = this.filter(configurations, autoConfigurationMetadata); this.fireAutoConfigurationImportEvents(configurations, exclusions); return (String[])configurations.toArray(new String[configurations.size()]); } catch (IOException var6) { throw new IllegalStateException(var6); } } }
1.是否開啟自動(dòng)配置,默認(rèn)開啟
protected boolean isEnabled(AnnotationMetadata metadata) { return true; }
2.從META-INF/spring-autoconfigure-metadata.properties文件中載入屬性配置
protected static final String PATH = "META-INF/spring-autoconfigure-metadata.properties"; private AutoConfigurationMetadataLoader() { } public static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader) { return loadMetadata(classLoader, "META-INF/spring-autoconfigure-metadata.properties"); } static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader, String path) { try { Enumeration<URL> urls = classLoader != null ? classLoader.getResources(path) : ClassLoader.getSystemResources(path); Properties properties = new Properties(); while(urls.hasMoreElements()) { properties.putAll(PropertiesLoaderUtils.loadProperties(new UrlResource((URL)urls.nextElement()))); } return loadMetadata(properties); } catch (IOException var4) { throw new IllegalArgumentException("Unable to load @ConditionalOnClass location [" + path + "]", var4); } }
3、獲取所有的配置列表
protected AnnotationAttributes getAttributes(AnnotationMetadata metadata) { String name = this.getAnnotationClass().getName(); AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(name, true)); Assert.notNull(attributes, "No auto-configuration attributes found. Is " + metadata.getClassName() + " annotated with " + ClassUtils.getShortName(name) + "?"); return attributes; }
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享關(guān)于SpringBoot Application注解原理分析內(nèi)容對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,遇到問題就找億速云,詳細(xì)的解決方法等著你來學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。