【springboot】入门
簡介:
springBoot是spring團(tuán)隊(duì)為了整合spring全家桶中的系列框架做研究出來的一個(gè)輕量級框架。隨著spring4.0推出而推出,springBoot可以説是J2SEE的一站式解決方案。在springboot之前如果需要開發(fā)一個(gè)大型的spring項(xiàng)目,可能需要掌握很多spring全家桶中的知識,但是springBoot出現(xiàn)后,開發(fā)人員只需要少量的配置就能實(shí)現(xiàn)項(xiàng)目的開發(fā),因?yàn)閟pringBoot已經(jīng)幫我們把一些常用的配置集合封裝好了,開發(fā)人員只需要非常少的代價(jià)就能打開J2EE企業(yè)級的大門。- 簡化Spring應(yīng)用開發(fā)的一個(gè)框架;
- 整個(gè)Spring技術(shù)棧的一個(gè)大整合;
- J2EE開發(fā)的一站式解決方案;
優(yōu)點(diǎn):
- 快速創(chuàng)建獨(dú)立運(yùn)行的Spring項(xiàng)目以及與主流框架集成
- 使用嵌入式的Servlet容器,應(yīng)用無需打成WAR包
- starters自動依賴與版本控制
- 大量的自動配置,簡化開發(fā),也可修改內(nèi)部配置的默認(rèn)值
- 無需配置XML,無代碼生成,開箱即用
- 準(zhǔn)生產(chǎn)環(huán)境的運(yùn)行時(shí)應(yīng)用監(jiān)控 與云計(jì)算的天然集成
缺點(diǎn):
入門容易精通難
微服務(wù):
微服務(wù)是一種架構(gòu)風(fēng)格,強(qiáng)調(diào)在開發(fā)一個(gè)應(yīng)用的時(shí)候,這個(gè)應(yīng)用應(yīng)該是一個(gè)小型服務(wù)的集合,每個(gè)小型服務(wù)運(yùn)行在自己的進(jìn)程內(nèi),這些小型服務(wù)通過http方式進(jìn)行通信。
之前存在一種一個(gè)單體應(yīng)用,即將所有的應(yīng)用放在一個(gè)工程中,然后將它打成jar包,部署到服務(wù)器上(tomcat),這種開發(fā)測試簡單,部署也簡單,水平擴(kuò)展也很容易。但是有一個(gè)最致命的問題就是牽一發(fā)動全身,雖然后來出現(xiàn)的分布式,,通過多個(gè)服務(wù)器復(fù)制單體進(jìn)行擴(kuò)展,但是并沒有解決根本問題。并且隨著需求的越來越大,每個(gè)小的應(yīng)用也越來越大,所有的應(yīng)用都集成到一起將會非常的龐大,所以開始有了微服務(wù)架構(gòu)。
微服務(wù)可以通過各個(gè)應(yīng)用的動態(tài)組合實(shí)現(xiàn)不同的工程功能,比如有的應(yīng)用比較重要,可能需要在每一個(gè)服務(wù)器上都進(jìn)行構(gòu)建,但是有的應(yīng)用并不重要可能值部署到其中一臺服務(wù)器上。
每一個(gè)功能元素最終都是一個(gè)可獨(dú)立替換和獨(dú)立升級的軟件單元;
微服務(wù)中的每個(gè)功能元素都是一個(gè)完整的功能單元,可能每一個(gè)功能項(xiàng)目都需要整合各種場景,一旦整個(gè)工程項(xiàng)目非常龐大,需要很多的功能單元,那每一功能單元都需要進(jìn)行項(xiàng)目的創(chuàng)建與環(huán)境整合,如果按照以前的創(chuàng)建項(xiàng)目的方式,我們將會浪費(fèi)很長時(shí)間去創(chuàng)建項(xiàng)目,但是SpringBoot出現(xiàn)之后,就可以應(yīng)用SpringBoot來進(jìn)行構(gòu)建,SpringBoot是一個(gè)輕量級框架。每個(gè)小的應(yīng)用元素使用springBoot進(jìn)行快速創(chuàng)建,各個(gè)元素之間使用springCloud進(jìn)行連接整合,進(jìn)行網(wǎng)上互連互調(diào),把整個(gè)工程的應(yīng)用模式做出來,那么在整個(gè)分布式中間可能需要數(shù)據(jù)的流式計(jì)算批處理等,就可以應(yīng)用到SpringCloud Data Flow。
所以應(yīng)用springBoot可以快速的構(gòu)建一個(gè)微服務(wù)單元。
入門:
項(xiàng)目搭建詳情見博客:SpringBoot項(xiàng)目搭建
解析內(nèi)部
依賴說明
1. 父項(xiàng)目
依賴中導(dǎo)入父項(xiàng)目:
<parent><groupId>org.springframework.boot</groupId><artifactId>spring‐boot‐starter‐parent</artifactId><version>1.5.9.RELEASE</version></parent>
查看源碼可知這個(gè)父項(xiàng)目的父項(xiàng)目是:
<parent><groupId>org.springframework.boot</groupId><artifactId>spring‐boot‐dependencies</artifactId><version>1.5.9.RELEASE</version><relativePath>../../spring‐boot‐dependencies</relativePath>
</parent>
dependencies:這是一個(gè)springBoot的版本仲裁中心,以后我們導(dǎo)入的jar包依賴默認(rèn)是不寫版本的(沒有在dependencies中管理的依賴還是需要聲明版本)
2. 啟動器
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring‐boot‐starter‐web</artifactId>
</dependency>
spring-boot-starter:是spring-boot場景啟動器;幫我們導(dǎo)入了web模塊正常運(yùn)行所依賴的組件;
Spring Boot將所有的功能場景都抽取出來,做成一個(gè)個(gè)的starters(啟動器),只需要在項(xiàng)目里面引入這些starter相關(guān)場景的所有依賴都會導(dǎo)入進(jìn)來,相關(guān)技術(shù)的大部分配置將會消除。要用什么功能就導(dǎo)入什么場景的啟動器。
這些starters幾乎涵蓋了javaee所有常用場景,Spring Boot對這些場景依賴的jar也做了嚴(yán)格的測試與版本控制。我們不必?fù)?dān)心jar版本合適度問題。
具體需要的啟動器可參考:啟動器
入口類執(zhí)行原理
/*** @SpringBootApplication 來標(biāo)注一個(gè)主程序類,說明這是一個(gè)Spring Boot應(yīng)用*/
@SpringBootApplication
public class SpringBootMainApplication {public static void main(String[] args) {//spring應(yīng)用啟動起來SpringApplication.run(SpringBootMainApplication.class,args);}
}
1. @SpringBootApplication
該注解是SpringBoot應(yīng)用注解,它標(biāo)注在某個(gè)類上說明這個(gè)類就是SpringBoot的主配置類,SpringBoot就應(yīng)該運(yùn)行這個(gè)類的main方法來啟動SpringBoot應(yīng)用;
注意:主方法內(nèi)部應(yīng)用springApplication方法來加載運(yùn)行類,一定要把標(biāo)注該注解的類文件作為參數(shù)傳進(jìn)去。
@SpringBootApplication注解按照源碼點(diǎn)擊進(jìn)去后會發(fā)現(xiàn)其內(nèi)部也標(biāo)注了很多注解,即該注解是一個(gè)復(fù)合注解,使用一個(gè)相當(dāng)于使用其內(nèi)部三個(gè)注解的功能:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
其中前四個(gè)注解就是我們非常熟悉的元注解(標(biāo)識該類是作為一個(gè)注解使用,并寫明相關(guān)屬性):
@Target 注解:指明了修飾的這個(gè)注解的使用范圍,即被描述的注解可以用在哪里。
ElementType 的取值:
- TYPE:類,接口或者枚舉;
- FIELD:域,包含枚舉常量;
- METHOD:方法;
- PARAMETER:參數(shù);
- CONSTRUCTOR:構(gòu)造方法;
- LOCAL_VARIABLE:局部變量;
- ANNOTATION_TYPE:注解類型;
- PACKAGE:包;
@Retention 注解:指明修飾的注解的生存周期,即會保留到哪個(gè)階段。
RetentionPolicy 的取值:
- SOURCE:源碼級別保留,編譯后即丟棄。
- CLASS:編譯級別保留,編譯后的class文件中存在,在jvm運(yùn)行時(shí)丟棄,這是默認(rèn)值。
- RUNTIME:運(yùn)行級別保留,編譯后的class文件中存在,在jvm運(yùn)行時(shí)保留,可以被反射調(diào)用。
@Documented 注解:表示該注解是否可以生成到 API文檔中,在該注解使用后,如果導(dǎo)出API文檔,會將該注解相關(guān)的信息可以被例如javadoc此類的工具文檔化。
@Inherited注解:允許子類繼承父類中的注解。
假設(shè)一個(gè)注解在定義時(shí),使用了@Inherited,然后該注解在一個(gè)類上使用,如果這個(gè)類有子類,那么通過反射我們可以從類的子類上獲取到同樣的注解。
后三個(gè)注解,@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan是@SpringBootApplication注解繼承來的,下面單獨(dú)講解其功能;
2. @SpringBootConfiguration
這個(gè)注解類上有@Configuration注解標(biāo)識,@Configuration是Spring 3.0時(shí)添加的一個(gè)注解(該配置類也是容器中的一個(gè)組件),用來代替 applicationContext.xml 配置文件,所有這個(gè)配置文件里面能做到的事情都可以通過這個(gè)注解所在類來進(jìn)行注冊。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
@SpringBootConfiguration繼承自@Configuration,二者功能也一致,標(biāo)注當(dāng)前類是配置類,并會將當(dāng)前類內(nèi)聲明的一個(gè)或多個(gè)以@Bean注解標(biāo)記的方法的實(shí)例納入到spring容器中,并且實(shí)例名就是方法名。
3. @EnableAutoConfiguration
該注解是一個(gè)核心注解,用于開啟自動配置功能,其內(nèi)部提供了強(qiáng)大的自動依賴功能,是SpringBoot這么方便的大功臣。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";Class<?>[] exclude() default {};String[] excludeName() default {};
}
這個(gè)注解也是一個(gè)復(fù)合注解。
(1) AutoConfigurationPackage
翻譯成人話就是自動配置包,把入口類所在包下的所有文件進(jìn)行掃描匹配,裝進(jìn)spring容器:
該注解主要的功能實(shí)現(xiàn)是由@Import({Registrar.class})來實(shí)現(xiàn)的。
Import注解也是Spring的底層注解,它用來給spring容器中導(dǎo)入一個(gè)組件,導(dǎo)入的組件由Registrar.class內(nèi)部指定。
Registrar.class這個(gè)類中有一個(gè)非常重要的靜態(tài)內(nèi)部類,用來將主配置類(@SpringBootApplication標(biāo)注的類)的所在包及下面所有子包里面的所有組件掃描到Spring容器中;
(2) @Import({AutoConfigurationImportSelector.class})
他存在的作用就是給容器中導(dǎo)入一些組件,具體哪些組件由AutoConfigurationImportSelector.class選擇(spring對J2EE中整合好的組件)。
AutoConfigurationImportSelector的意思就是開啟自動配置類的導(dǎo)包的選擇器(導(dǎo)入哪些組件的選擇器)
那么到底需要導(dǎo)入哪些配置類,代碼運(yùn)行是怎么知道的呢(也就是上面圖片中的configurations參數(shù)內(nèi)容) ,這就用到了該類中的另一個(gè)方法getCandidateConfigurations。
該方法中調(diào)用了SpringFactoriesLoader類中的loadFactoryNames方法:
SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader)
它的作用總結(jié)就是:
1、掃描所有jar包類路徑下 META‐INF/spring.factories。
2、把掃描到的這些文件的內(nèi)容包裝成properties對象。
3、從properties中獲取到EnableAutoConfiguration.class類(類名)對應(yīng)的值,然后把他們添加在容器中。
Spring Boot在啟動的時(shí)候從類路徑下的META-INF/spring.factories中獲取EnableAutoConfiguration指定的值,將
這些值作為自動配置類導(dǎo)入到容器中,自動配置類就生效,幫我們進(jìn)行自動配置工作;以前我們需要自己配置的東西,自動配置類都幫我們;
J2EE的整體整合解決方案和自動配置都在spring-boot-autoconfigure-1.5.9.RELEASE.jar;
自動配置原理
以HttpEncodingAutoConfiguration(Http編碼自動配置)為例解釋自動配置原理。
@Configuration
@EnableConfigurationProperties(HttpProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
1. Configuration
表明這是一個(gè)配置類,和以前編寫的配置文件一樣,可以給容器中添加組件
@EnableConfigurationProperties
啟動指定類的ConfigurationProperties功能,這里開啟的是HttpProperties類的ConfigurationProperties功能。將配置文件中對應(yīng)的值和HttpEncodingProperties綁定起來。
所有的配置文件(這里只的是yml文件)中能配置的屬性都是在xxxxProperties類(這里是HttpProperties.class)中封裝著,配置文件能配置什么 就可以參照某個(gè)功能對應(yīng)的這個(gè)屬性類。
2. @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
spring底層有一個(gè)@Conditional注解,它會根據(jù)不同條件判斷,如果滿足指定的條件,整個(gè)配置類就會生效。
在這里判斷的是當(dāng)前應(yīng)用是否是web應(yīng)用,如果是,當(dāng)前配置類生效。
3. @ConditionalOnClass(CharacterEncodingFilter.class)
判斷當(dāng)前項(xiàng)目有沒有CharacterEncodingFilter這個(gè)類,這個(gè)類是springmvc中進(jìn)行亂碼解決的過濾器。
4. @ConditionalOnProperty(prefix = “spring.http.encoding”, value = “enabled”, matchIfMissing = true)
判斷配置文件中是否存在某個(gè)配置 spring.http.encoding.enabled;如果不存在,判斷也是成立的;
即使我們配置文件中不配置pring.http.encoding.enabled=true,也是默認(rèn)生效的;
@Configuration //表示這是一個(gè)配置類,以前編寫的配置文件一樣,也可以給容器中添加組件@EnableConfigurationProperties(HttpProperties.class)//啟動指定類的ConfigurationProperties功能;
將配置文件中(本類中)對應(yīng)的值和HttpProperties綁定起來;并把HttpProperties加入到ioc容器中。@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)//Spring底層@Conditional注解(Spring注解版),根據(jù)不同的條件,如果
滿足指定的條件,整個(gè)配置類里面的配置就會生效; 判斷當(dāng)前應(yīng)用是否是web應(yīng)用,如果是,當(dāng)前配置類生效@ConditionalOnClass(CharacterEncodingFilter.class)//判斷當(dāng)前項(xiàng)目有沒有這個(gè)類CharacterEncodingFilter;
SpringMVC中進(jìn)行亂碼解決的過濾器。@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
//判斷配置文件中是否存在某個(gè)配置 spring.http.encoding.enabled;如果不存在,判斷也是成立的。
//即使我們配置文件中不配置pring.http.encoding.enabled=true,也是默認(rèn)生效的;public class HttpEncodingAutoConfiguration {//他已經(jīng)和SpringBoot的配置文件映射了 private final HttpProperties.Encoding properties;//只有一個(gè)有參構(gòu)造器的情況下,參數(shù)的值就會從容器中拿public HttpEncodingAutoConfiguration(HttpProperties properties) {this.properties = properties.getEncoding();}@Bean //給容器中添加一個(gè)組件,這個(gè)組件的某些值需要從properties中獲取@ConditionalOnMissingBean //判斷容器有沒有這個(gè)組件public CharacterEncodingFilter characterEncodingFilter() {CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();filter.setEncoding(this.properties.getCharset().name());filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));return filter;}
根據(jù)當(dāng)前不同的條件判斷,決定這個(gè)配置類是否生效。一但這個(gè)配置類生效;這個(gè)配置類就會給容器中添加各種組件;這些組件的屬性是從對應(yīng)的properties類中獲取的,這些類里面的每一個(gè)屬性又是和配置文件綁定的;
5. 精髓
1.SpringBoot啟動會加載大量的自動配置類
2.我們看我們需要的功能有沒有SpringBoot默認(rèn)寫好的自動配置類;
3.我們再來看這個(gè)自動配置類中到底配置了哪些組件;(只要我們要用的組件有,我們就不需要再來配置了)
4.給容器中自動配置類添加組件的時(shí)候,會從properties類中獲取某些屬性。我們就可以在配置文件中指定這些屬性的值;
xxxxAutoConfigurartion:自動配置類;給容器中添加組件;
xxxxProperties:封裝配置文件中相關(guān)屬性;
6. 細(xì)節(jié)
@Conditional派生注解:必須是@Conditional指定的條件成立,才給容器中添加組件,配置配里面的所有內(nèi)容才生效;自動配置類必須在一定的條件下才能生效;
我們怎么知道哪些自動配置類生效?我們可以通過啟用 debug=true屬性;來讓控制臺打印自動配置報(bào)告,這樣我們就可以很方便的知道哪些自動配置類生效;
=========================
AUTO‐CONFIGURATION REPORT
=========================
Positive matches:(自動配置類啟用的)
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐DispatcherServletAutoConfiguration matched:‐ @ConditionalOnClass found required class
'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find
unwanted class (OnClassCondition)‐ @ConditionalOnWebApplication (required) found StandardServletEnvironment
(OnWebApplicationCondition)Negative matches:(沒有啟動,沒有匹配成功的自動配置類)
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ActiveMQAutoConfiguration:Did not match:‐ @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory',
'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)AopAutoConfiguration:Did not match:‐ @ConditionalOnClass did not find required classes
'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice' (OnClassCondition)
使用Spring Initializer快速創(chuàng)建
IDE都支持使用Spring的項(xiàng)目創(chuàng)建向?qū)Э焖賱?chuàng)建一個(gè)Spring Boot項(xiàng)目;
選擇我們需要的模塊;向?qū)?lián)網(wǎng)創(chuàng)建Spring Boot項(xiàng)目;
默認(rèn)生成的Spring Boot項(xiàng)目;
主程序已經(jīng)生成好了,我們只需要我們自己的邏輯;
resources文件夾中目錄結(jié)構(gòu):
static:保存所有的靜態(tài)資源; js css images;
templates:保存所有的模板頁面;(Spring Boot默認(rèn)jar包使用嵌入式的Tomcat,默認(rèn)不支持JSP頁面);可以使用模板引擎(freemarker、thymeleaf);
application.properties:Spring Boot應(yīng)用的配置文件;可以修改一些默認(rèn)設(shè)置;
總結(jié)
以上是生活随笔為你收集整理的【springboot】入门的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【J2SE】语言基础
- 下一篇: 【springboot】配置