淺學(xué)Spring Boot

淺學(xué)Spring Boot

Spring Boot是Spring的擴(kuò)展,在保持了Spring原有兩大特性的前提下又提出了新的功能。

因此,正式介紹Spring Boot之前,我們不妨先來探尋一下Spring是個(gè)什么東西!

Spring

框架開發(fā)的初心都是為了降低程序員寫代碼時(shí)的復(fù)雜度,能夠讓程序員將自己的精力盡可能多的集中到自己的邏輯開發(fā)上面,而不是在開發(fā)環(huán)境的配置上面。為了實(shí)現(xiàn)這一點(diǎn),Spring提出了以下兩個(gè)技術(shù):面向切面編程和依賴注入。

面向切面編程(AOP)

面向切面編程,通俗來說就是把專業(yè)的活交給專業(yè)的人來干。舉個(gè)例子,就像在學(xué)校里有很多食堂,這些食堂都被不同的餐飲公司所承包,這里被承包了的食堂就是切面。這樣做有什么好處呢,很明顯,食堂承包出去之后由于餐飲公司是專門做餐飲的,那飯菜肯定比學(xué)校自己做的好吃,而且學(xué)校將餐飲業(yè)務(wù)承包出去之后,就可以將自己更多的精力放在教書育人上邊,專注于自己的本職業(yè)務(wù),如果對承包商不滿意還可以即時(shí)的更換其他承包商(更換切面),真是個(gè)一舉多得的好事情,在編程當(dāng)中,什么是這些切面呢?對象與對象之間,方法與方法之間,模塊與模塊之間都是一個(gè)個(gè)這樣的切面。

單一職責(zé)原則:類應(yīng)該是純凈的,不應(yīng)含有與本身無關(guān)的邏輯。

面向切面編程,可以帶來代碼的解耦,使得各個(gè)模塊專注于自身的業(yè)務(wù)邏輯,提高開發(fā)效率。

使用AOP之前,我們需要理解幾個(gè)概念。

image

傳送門:Spring 之 AOP

  • 連接點(diǎn)(Join Point):

所有可能的需要注入切面的地方。比如方法前后,類初始化、屬性初始化前后。

  • 切點(diǎn)(Poincut):

需要做某些處理的連接點(diǎn)(連接點(diǎn)有很多,但是真正切入的連接點(diǎn)才叫切點(diǎn)),比如打印日志、處理緩存等,存在于切面當(dāng)中。目前,Spring只支持方法的切點(diǎn)定義。

  • 通知(Advice):

定義在什么時(shí)候,做什么事情。Spring支持5種方法上的通知類型。

@Before:在目標(biāo)方法被調(diào)用之前調(diào)用。

@After:通知方法會在目標(biāo)方法返回或拋出異常之后調(diào)用。

@AfterReturning:通知方法會在目標(biāo)方法返回后調(diào)用。

@AfterThrowing:通知方法會在目標(biāo)方法拋出異常之后調(diào)用。

@Around:相當(dāng)于Befor和After的結(jié)合。

  • 切面(Aspect)

通知+切點(diǎn)的集合,定義在什么地方什么時(shí)間做什么事情。


@Aspect

public class Audience {

    @Autowired

    private CriticismEngineImpl criticismEngine;

    @Pointcut(

            "execution(* com.example.aoptest.impl.Performance.perform(int))"+"&& args(ha)")//將perform函數(shù)視為切點(diǎn)

    public void performance(int ha) {}//該方法本身只是個(gè)標(biāo)識,供Advice依附,對performance函數(shù)的通知相當(dāng)于對切點(diǎn)perform函數(shù)的通知。

    @Before("performance(ha)")//通知

   public    void silenceCellPhones(int ha)

    {

        ha++;

        System.out.println(ha);

        System.out.println("前置通知:Sillencing cell phones");

    }

}

  • 引入(Introduction)

允許我們向現(xiàn)有的類添加新方法或?qū)傩浴>褪前亚忻嬗玫侥繕?biāo)類當(dāng)中,在不修改目標(biāo)類的條件下為目標(biāo)類添加新的屬性和方法。

依賴注入

在Java程序中,一個(gè)業(yè)務(wù)邏輯經(jīng)常需要兩個(gè)或兩個(gè)以上的對象協(xié)作來完成,通常每個(gè)對象在使用他的合作對象時(shí),自己均要使用像new object()這樣的語法來完成合作對象的申請工作,這樣會使得對象之間的耦合度較高,程序結(jié)構(gòu)比較復(fù)雜。而依賴注入的思想是:由Spring來負(fù)責(zé)控制對象的生命周期和對象間的關(guān)系,對象只需要負(fù)責(zé)關(guān)心業(yè)務(wù)邏輯就好了。

創(chuàng)建應(yīng)用對象之間協(xié)作關(guān)系的行為通常稱為裝配(wiring),這也是依賴注入的本質(zhì)。在Spring中依賴注入有多種方式,我們在這里先來介紹一下配置Spring容器最常見的三種方法。

自動(dòng)化裝配bean

Spring從兩個(gè)角度來實(shí)現(xiàn)自動(dòng)化裝配:

  • 組件掃描(component scanning):Spring會自動(dòng)發(fā)現(xiàn)應(yīng)用上下文中所創(chuàng)建的bean。

  • 自動(dòng)裝配(autowiring):Spring自動(dòng)實(shí)現(xiàn)bean之間的依賴。

為了闡述組件掃描和裝配,我們需要裝配幾個(gè)bean,它們代表一個(gè)音響系統(tǒng)中的組件。首先,創(chuàng)建一個(gè)CompactDisc接口和它的實(shí)現(xiàn)CompactDiscImp,并將其創(chuàng)建為一個(gè)bean。然后,會創(chuàng)建一個(gè)CDPlayer類,讓Spring發(fā)現(xiàn)它,并將bean注入進(jìn)來。

CompactDisc接口在Java中定義了CD的概念


public interface CompactDisc{

    void play();

}

我們將CompactDisc定義為一個(gè)接口,它定義了CD播放器的一系列操作,而且作為接口,它將CD的任意實(shí)現(xiàn)與CD本身的耦合降低到了最小的程度。這里,我們還需要一個(gè)CD的實(shí)現(xiàn),也就是CompactDiscImp類。

CompactDiscImp實(shí)現(xiàn)類


@Component

public class  CompactDiscImp implements CompactDisc{

    private String title = "這是實(shí)現(xiàn)類";

    public void play()

    {

        System.out.println(title);

    }

}

和接口一樣,CompactDiscImp的具體內(nèi)容并不重要,你需要注意的是CompactDiscImp類上使用了@Component注解。這個(gè)簡單的注解表明該類會作為組件類,并告知Spring要為這個(gè)類創(chuàng)建bean。不過,組件掃描默認(rèn)是不啟用的。我們還需要顯示配置Spring,從而命令它去尋找?guī)в蠤Component注解的類,并為其創(chuàng)建bean。

@ComponentScan注解啟用了組件掃描(CDPlayerConfig.class)


@Configurzation

@ComponentScan

public class CDPlayerConfig

{

}

類CDPlayerConfig通過Java代碼定義了Spring的裝配規(guī)則。在本文后部分,我們還會更為詳細(xì)的介紹基于Java的Spring配置。不過,現(xiàn)在我們只需觀察CDPlayerConfig類并沒有顯示地聲明任何bean,只不過它使用了@ComponentScan注解,這個(gè)注解能夠在Spring中啟用組件掃描,使得Spring去尋找?guī)в蠤ComponentScan注解地類,并為其創(chuàng)建bean。(此處也可以通過使用XML來啟用組件掃描,但作者更喜歡使用JAVA配置,這里就不做贅述,如果有對XML配置感興趣的,可以去查看Spring in Action的第二章)

通過自動(dòng)裝配,將一個(gè)CompactDisc注入到CDPlayer之中


public class CDPlayer

{

    @Autowired//由于本實(shí)例只有一種實(shí)現(xiàn)類,所以默認(rèn)注入對象為CompactDiscImp的實(shí)例,若有多個(gè)實(shí)現(xiàn)類,可用@Qualifier注解加以區(qū)分

    private CompactDisc cd;//不通過new對象的方式,而是通過注入的形式創(chuàng)建了一個(gè)其他類的對象

    cd.play();//會打印出“這是實(shí)現(xiàn)類”

}

這就實(shí)現(xiàn)了,自動(dòng)裝備bean的方式。

通過Java代碼裝配bean

盡管在很多場景下通過組件掃描和自動(dòng)裝配實(shí)現(xiàn)Spring的自動(dòng)化配置是更為推薦的方式,但有時(shí)候自動(dòng)化配置的方案行不通,因此需要明確配置Spring。比如說,你想要將第三方庫中的組件配到你的應(yīng)用當(dāng)中,這種情況你無法直接在第三方庫的源碼上添加@Component和@Autowired注解,因此就不能使用自動(dòng)化裝配的方案了。

在這種情況下,你必須要采用顯示裝配的方式。在進(jìn)行顯示配置的時(shí)候,有兩種方案可選:Java和XML。XML我在這里不作贅述,有興趣的同學(xué)可以自行查閱《Spring in Action》第二章第四節(jié),在這里我只介紹使用Java進(jìn)行配置的方式。

進(jìn)行顯示配置時(shí),JavaConfig是更好的方案,因?yàn)樗鼮閺?qiáng)大,類型安全而且對于重構(gòu)比較友好,不同于其他的Java代碼,JavaConfig是配置代碼,它不應(yīng)該含有任何業(yè)務(wù)邏輯,最好將其放在業(yè)務(wù)邏輯之外的包中。還是之前的例子。

@ComponentScan注解啟用了組件掃描(CDPlayerConfig.class)


@Configurzation

@ComponentScan

public class CDPlayerConfig

{

}

創(chuàng)建JavaConfig類的關(guān)鍵在于為其添加@Configuration注解,@Configuration注解表明這個(gè)類是一個(gè)配置類。@ComponentScan啟用了組件掃描,這是實(shí)現(xiàn)自動(dòng)裝配的關(guān)鍵。但如果我們將@ComponentScan注解移除,此時(shí)的@CDPlayerConfig類就不會有任何作用了,現(xiàn)在再運(yùn)行主函數(shù),會拋出BeanCreation-Exception異常。這是因?yàn)橹骱瘮?shù)期望被注入CompactDisc,但是這些bean根本就沒有被創(chuàng)建,那我們?nèi)绾芜M(jìn)行顯式的java配置呢?

要在JavaConfig中聲明bean,我們需要編寫一個(gè)方法,這個(gè)方法會創(chuàng)建所需類型的實(shí)例,然后給這個(gè)方法添加@Bean注解。

使用Javaconfig顯式裝配bean(CDPlayerConfig.class)


@Configurzation

public class CDPlayerConfig

{

    @Bean

    public CompactDisc javaconfig()

    {

        return new CompactDiscImp();

    }

}

@Bean注解會告訴Spring這個(gè)方法會返回一個(gè)對象,該對象要注冊為Spring應(yīng)用上下文中的bean。

通過Java裝配,將一個(gè)CompactDisc注入到CDPlayer之中


public class CDPlayer

{

    @Autowired//由于本實(shí)例只有一種實(shí)現(xiàn)類,所以默認(rèn)注入對象為CompactDiscImp的實(shí)例,若有多個(gè)實(shí)現(xiàn)類,可用@Qualifier注解加以區(qū)分

    private CompactDisc cd;//不通過new對象的方式,而是通過注入的形式創(chuàng)建了一個(gè)其他類的對象

    cd.play();//會打印出“這是實(shí)現(xiàn)類”

}

Spring Boot

Spring Boot是Spring的擴(kuò)展,在Spring的AOP(面向切面編程)和DI(依賴注入)兩個(gè)特性的基礎(chǔ)上又完善了以下四個(gè)功能。

  • 自動(dòng)配置:針對很多Spring應(yīng)用程序所常見的應(yīng)用功能,Spring boot能自動(dòng)提供相關(guān)配置。

  • 起步依賴:告訴Spring Boot需要什么功能,它就能引入需要的庫。

  • 命令行界面:這是Spring Boot的可選特性,借此你只需寫代碼就能完成完整的應(yīng)用程序,無需傳統(tǒng)項(xiàng)目構(gòu)建。

  • Actuator:讓你能夠深入運(yùn)行中的Spring Boot應(yīng)用程序,一探究竟。

自動(dòng)配置

在任何Spring應(yīng)用的源碼中,你都會找到Java配置或XML配置(自動(dòng)化配置難以配置第三方庫中的組件),它們?yōu)閼?yīng)用程序開啟了特定的特性和功能。舉個(gè)例子,如果你寫過用JDBC訪問關(guān)系型數(shù)據(jù)庫的應(yīng)用程序,那你一定在Spring應(yīng)用程序上下文里配置過JdbcTemplate這個(gè)Bean。


@Bean

public JdbcTemplate jdbcTemplate(DataSource dataSource){

    return new JdbcTemplate(dataSource);

}

這段非常簡單的Bean聲明創(chuàng)建了一個(gè)JdbcTemplate的實(shí)例,注入了一個(gè)DataSource依賴,這意味著你還需要配置一個(gè)DataSource的Bean,這樣才能滿足依賴。

雖然這兩個(gè)Bean配置方法都不復(fù)雜,也不是很長,但它們只是Spring應(yīng)用程序配置的一小部分。除此之外,還有無數(shù)Sping應(yīng)用程序有著類似的配置方法,簡而言之,這就是個(gè)樣板配置。

既然它如此常見,那我們有沒有辦法可以自動(dòng)配置這些Bean而不是每次手動(dòng)去寫配置代碼呢?

Spring Boot做到了這點(diǎn),它會為這些常見配置場景進(jìn)行自動(dòng)配置。如果Spring Boot在應(yīng)用程序的ClassPath里發(fā)現(xiàn)了JdbcTemplate,那么它會為你配置一個(gè)JdbcTemplate的Bean,如果在應(yīng)用程序的Classpath里發(fā)現(xiàn)了DataSource,那么他還會為你創(chuàng)建一個(gè)DataSource的Bean。你無需擔(dān)心那些Bean的配置,Spring Boot會做好準(zhǔn)備,隨時(shí)都能將其注入到你的Bean當(dāng)中。這就是Spring Boot的自動(dòng)配置.

起步依賴

Spring boot通過起步依賴為項(xiàng)目的依賴管理提供幫助。起步依賴就是特殊的Maven依賴和Gradle依賴,利用傳遞依賴解析,幫常用庫聚合在一起。舉個(gè)例子,假如你正在用Spring MVC構(gòu)造REST API,并使用JSON作為資源表述。此外,你還想使用JSR-303規(guī)范的聲明式校驗(yàn),并使用嵌入式Tomcat服務(wù)器來提供服務(wù)。要實(shí)現(xiàn)以上目標(biāo),你在Maven或Gradle里至少需要以下8個(gè)依賴:

org.springframework:spring-core

org.springframework:spring-web

org.springframework:spring-webmvc

com.fasterxml.jackson.core:jackson-databind

org.hibernate:hibernate-validator

org.apache.tomcat.embed:tomcat-embed-core

org.apache.tomcat.embed:tomcat-embed-el

org.apache.tomcat.embed:tomcat-embed-logging-juli

如果打算使用Spring Boot的起步依賴,你只需要添加Spring Boot的Web起步依賴(org.springframework.boot:spring-boot-starter-web),僅此一個(gè)。它會根據(jù)依賴傳遞把其他所需依賴引入項(xiàng)目里。

比起減少依賴數(shù)量,起步依賴還有一個(gè)好處就是:你不再需要考慮支持某種功能需要使用什么庫了,直接引入相關(guān)依賴就行。如果應(yīng)用是個(gè)Web應(yīng)用,所以加入了Web起步依賴;如果應(yīng)用程序要用到JPA持久化,那么就可以加入JPA起步依賴;需要安全功能,直接加入security起步依賴即可。

命令行界面

除了自動(dòng)配置和起步依賴,Spring Boot還提供了一種很有意思的開發(fā)spring boot應(yīng)用的新方法。Spring Boot Cli讓只寫代碼即可實(shí)現(xiàn)應(yīng)用程序成為可能。

Spring Boot Cli利用了起步依賴和自動(dòng)配置,讓你專注于代碼本身。簡單來說,CLI能檢測到你使用了哪些類,它知道要向Classpath中添加哪些起步依賴才能讓它運(yùn)轉(zhuǎn)起來,一旦那些依賴出現(xiàn)在Classpath中,一系列自動(dòng)配置就會接踵而來。

但同時(shí),Spring Boot Cli是Spring Boot的非必要組成部分,雖然它為Spring帶來了驚人的力量,大大簡化了開發(fā),但也引入了一套不太常規(guī)的開發(fā)模型。如果您還是不太適應(yīng)這種開發(fā)模型,可以拋開CLI,利用Spring Boot提供的其他東西。

Actuator

Spring Boot的最后一個(gè)法寶就是Actuator,其他幾個(gè)部分旨在簡化Spring配置,而Actuator則要在提供運(yùn)行時(shí)檢查應(yīng)用程序內(nèi)部情況的能力。包括以下細(xì)節(jié):

  • Spring應(yīng)用程序上下文配置的Bean。

  • 應(yīng)用程序取到的環(huán)境變量、系統(tǒng)屬性、配置屬性和命令行參數(shù)。

  • 應(yīng)用程序中線程的當(dāng)前狀態(tài)。

  • 應(yīng)用程序最近處理過的Http請求追蹤情況。

  • 各種和內(nèi)存用量,垃圾回收、Web請求相關(guān)的指標(biāo)。

傳送門,使用Spring Boot Actuator監(jiān)控應(yīng)用

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容