javascript
SpringBoot 源码解析 (一)----- SpringBoot核心原理入门
目錄
Spring Boot 概述
什么是 Spring Boot
使用 Spring Boot 有什么好處
Spring Boot HelloWorld
導(dǎo)入依賴spring boot相關(guān)的依賴
編寫(xiě)主程序
編寫(xiě)Controller、Service
運(yùn)行主程序測(cè)試
Hello World探究
POM文件
啟動(dòng)器
主程序類(主入口類)
Spring Boot 概述
Build Anything with Spring Boot:Spring Boot is the starting point for building all Spring-based applications. Spring Boot is designed to get you up and running as quickly as possible, with minimal upfront configuration of Spring.
上面是引自官網(wǎng)的一段話,大概是說(shuō): Spring Boot 是所有基于 Spring 開(kāi)發(fā)的項(xiàng)目的起點(diǎn)。Spring Boot 的設(shè)計(jì)是為了讓你盡可能快的跑起來(lái) Spring 應(yīng)用程序并且盡可能減少你的配置文件。
什么是 Spring Boot
它使用 “習(xí)慣優(yōu)于配置” (項(xiàng)目中存在大量的配置,此外還內(nèi)置一個(gè)習(xí)慣性的配置,讓你無(wú)須手動(dòng)配置)的理念讓你的項(xiàng)目快速運(yùn)行起來(lái)。
它并不是什么新的框架,而是默認(rèn)配置了很多框架的使用方式,就像 Maven 整合了所有的 jar 包一樣,Spring Boot 整合了所有框架
使用 Spring Boot 有什么好處
回顧我們之前的 SSM 項(xiàng)目,搭建過(guò)程還是比較繁瑣的,需要:
1)配置 web.xml,加載 spring 和 spring mvc
2)配置數(shù)據(jù)庫(kù)連接、配置日志文件
3)配置家在配置文件的讀取,開(kāi)啟注解
4)配置mapper文件
…
而使用 Spring Boot 來(lái)開(kāi)發(fā)項(xiàng)目則只需要非常少的幾個(gè)配置就可以搭建起來(lái)一個(gè) Web 項(xiàng)目,并且利用 IDEA 可以自動(dòng)生成生成
劃重點(diǎn):簡(jiǎn)單、快速、方便地搭建項(xiàng)目;對(duì)主流開(kāi)發(fā)框架的無(wú)配置集成;極大提高了開(kāi)發(fā)、部署效率。
回到頂部
Spring Boot HelloWorld
導(dǎo)入依賴spring boot相關(guān)的依賴
4.0.0
/**
-
@SpringBootApplication來(lái)標(biāo)注一個(gè)主程序類,說(shuō)明這是一個(gè)SpringBoot應(yīng)用
*/
@SpringBootApplication
public class HelloWorldMainApplication {public static void main(String[] args) {
//Spring應(yīng)用啟動(dòng)
SpringApplication.run(HelloWorldMainApplication.class, args);
}
}
編寫(xiě)Controller、Service
@RestController
public class HelloController {
}
運(yùn)行主程序測(cè)試
使用maven打包命令將其打包成jar包后,直接使用命令:
java -jar xxx.jar
回到頂部
Hello World探究
POM文件
父項(xiàng)目
該父項(xiàng)目是真正管理Spring Boot應(yīng)用里面的所有依賴的版本:Spring Boot的版本仲裁中心,所以以后導(dǎo)入的依賴默認(rèn)是不需要版本號(hào)。如下
還有很多版本號(hào)沒(méi)有截圖出來(lái)
啟動(dòng)器
org.springframework.boot
spring-boot-starter-web
? spring-boot-starter : spring boot場(chǎng)景啟動(dòng)器;幫助導(dǎo)入web模塊正常運(yùn)行所依賴的組件;
? Spring Boot將所有的功能場(chǎng)景抽取出來(lái),做成一個(gè)個(gè)的starter(啟動(dòng)器),只需要在項(xiàng)目中引入這些starter,那么相關(guān)的場(chǎng)景的所有依賴都會(huì)導(dǎo)入進(jìn)項(xiàng)目中。要用什么功能就導(dǎo)入什么場(chǎng)景的啟動(dòng)器。
org.springframework.boot spring-boot-starter-tomcat org.springframework spring-web org.springframework spring-webmvc添加了 spring-boot-starter-web 依賴,會(huì)自動(dòng)添加 Tomcat 和 Spring MVC 的依賴
spring-boot-starter-web中又引入了spring-boot-starter-tomcat
@SpringBootApplication
public class HelloWorldMainApplication {
}
@SpringBootApplication
Spring Boot應(yīng)用標(biāo)注在某個(gè)類上,說(shuō)明這個(gè)類是SpringBoot的主配置類,SpringBoot就應(yīng)該運(yùn)行這個(gè)類的main方法來(lái)啟動(dòng)SpringBoot應(yīng)用。
注解定義如下:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {}
@SpringBootConfiguration
Spring Boot的配置類
標(biāo)注在某個(gè)類上,表示這是一個(gè)Spring Boot的配置類
注解定義如下:
@Configuration
public @interface SpringBootConfiguration {}
其實(shí)就是一個(gè)Configuration配置類,意思是HelloWorldMainApplication最終會(huì)被注冊(cè)到Spring容器中
@EnableAutoConfiguration
開(kāi)啟自動(dòng)配置功能
以前使用Spring需要配置的信息,Spring Boot幫助自動(dòng)配置;
@EnableAutoConfiguration通知SpringBoot開(kāi)啟自動(dòng)配置功能,這樣自動(dòng)配置才能生效。
注解定義如下:
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}
@AutoConfigurationPackage
自動(dòng)配置包注解
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {}
@Import(AutoConfigurationPackages.Registrar.class):默認(rèn)將主配置類(@SpringBootApplication)所在的包及其子包里面的所有組件掃描到Spring容器中。如下
@Order(Ordered.HIGHEST_PRECEDENCE)
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
}
@Import(EnableAutoConfigurationImportSelector.class)
EnableAutoConfigurationImportSelector: 導(dǎo)入哪些組件的選擇器,將所有需要導(dǎo)入的組件以全類名的方式返回,這些組件就會(huì)被添加到容器中。
//EnableAutoConfigurationImportSelector的父類:AutoConfigurationImportSelector
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
try {
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List configurations = getCandidateConfigurations(annotationMetadata, attributes);
configurations = removeDuplicates(configurations);
configurations = sort(configurations, autoConfigurationMetadata);
Set exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return configurations.toArray(new String[configurations.size()]);
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
我們主要看第11行List configurations = getCandidateConfigurations(annotationMetadata, attributes);會(huì)給容器中注入眾多的自動(dòng)配置類(xxxAutoConfiguration),就是給容器中導(dǎo)入這個(gè)場(chǎng)景需要的所有組件,并配置好這些組件。我們跟進(jìn)去看看
protected List getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes) {
List configurations = SpringFactoriesLoader.loadFactoryNames(
getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
//…
return configurations;
}
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
public static final String FACTORIES_RESOURCE_LOCATION = “META-INF/spring.factories”;
public static List loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
try {
//從類路徑的META-INF/spring.factories中加載所有默認(rèn)的自動(dòng)配置類
Enumeration urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
List result = new ArrayList();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
//獲取EnableAutoConfiguration指定的所有值,也就是EnableAutoConfiguration.class的值
String factoryClassNames = properties.getProperty(factoryClassName);
result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
}
return result;
}
catch (IOException ex) {
throw new IllegalArgumentException(“Unable to load [” + factoryClass.getName() + “] factories from location [” + FACTORIES_RESOURCE_LOCATION + “]”, ex);
}
}
SpringBoot啟動(dòng)的時(shí)候從類路徑下的 META-INF/spring.factories中獲取EnableAutoConfiguration指定的值,并將這些值作為自動(dòng)配置類導(dǎo)入到容器中,自動(dòng)配置類就會(huì)生效,最后完成自動(dòng)配置工作。EnableAutoConfiguration默認(rèn)在spring-boot-autoconfigure這個(gè)包中,如下圖
最終有96個(gè)自動(dòng)配置類被加載并注冊(cè)進(jìn)Spring容器中
J2EE的整體整合解決方案和自動(dòng)配置都在spring-boot-autoconfigure-xxx.jar中。在這些自動(dòng)配置類中會(huì)通過(guò)@ConditionalOnClass等條件注解判斷是否導(dǎo)入了某些依賴包,從而通過(guò)@Bean注冊(cè)相應(yīng)的對(duì)象進(jìn)行自動(dòng)配置。后面我們會(huì)有單獨(dú)文章講自動(dòng)配置的內(nèi)容
總結(jié)
以上是生活随笔為你收集整理的SpringBoot 源码解析 (一)----- SpringBoot核心原理入门的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: hashmap 判断key是否存在
- 下一篇: SpringBoot配置嵌入式Servl