《深入實(shí)踐SpringBoot》閱讀筆記之三:核心技術(shù)源代碼分析-創(chuàng)新互聯(lián)

剛關(guān)注的朋友,可以回顧前兩篇文章:

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶,將通過(guò)不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:空間域名、網(wǎng)絡(luò)空間、營(yíng)銷軟件、網(wǎng)站建設(shè)、烏蘭察布網(wǎng)站維護(hù)、網(wǎng)站推廣。
  • 基礎(chǔ)應(yīng)用開發(fā)
  • 分布式應(yīng)用開發(fā)

上篇文章總結(jié)了《深入實(shí)踐Spring Boot》的第二部分,本篇文章總結(jié)第三部分,也是最后一部分。這部分主要講解核心技術(shù)的源代碼分析,因?yàn)槠湍芰υ?,分析的不?huì)太詳細(xì),后續(xù)深入研究后再專門寫文章。希望大家能從「閱讀筆記」3篇文章中,對(duì)Spring Boot提供的功能有所了解,在項(xiàng)目中進(jìn)行實(shí)踐,不斷從繁瑣重復(fù)的開發(fā)中解放出來(lái)。

我也是最近剛開始了解Spring Boot,計(jì)劃今年在項(xiàng)目中實(shí)踐,到時(shí)會(huì)總結(jié)實(shí)踐過(guò)程中的一些問題和經(jīng)驗(yàn),分享給大家。想一起學(xué)習(xí)、實(shí)踐、交流的朋友,可以掃描文章下方的二維碼,關(guān)注我的個(gè)人公眾號(hào),感謝大家。

本篇主要從以下幾個(gè)方面總結(jié):

  • Spring Boot自動(dòng)配置實(shí)現(xiàn)原理;
  • Spring Boot數(shù)據(jù)訪問實(shí)現(xiàn)原理;
  • 微服務(wù)核心技術(shù)實(shí)現(xiàn)原理;
題外話

春節(jié)假期很快過(guò)去了,明天就要上班了,相信大家還是意猶未盡,沒吃夠、沒玩夠、沒和家人待夠。今年因?yàn)閭€(gè)人原因,沒有回家過(guò)年,心理最牽掛的還是爺爺奶奶,他們都80多了,希望她們身體健康,開開心心地度過(guò)生命最后的旅程。

不管怎樣,大家要切換頻道了,回歸到正常的工作中,好好努力,一起期待明年和家人更好的團(tuán)聚。

Spring Boot自動(dòng)配置實(shí)現(xiàn)原理

使用Spring Boot創(chuàng)建一個(gè)簡(jiǎn)單的Web項(xiàng)目很簡(jiǎn)潔,不需要太多配置,編寫一個(gè)簡(jiǎn)單的主程序就行:

@SpringBootApplication
public class ConfigApplication{
    public static void main(String[] args) {
        SpringApplication.run(ConfigApplication.class, args);
}
主程序分析

首先分析下run方法(省略不關(guān)鍵的部分代碼):

public ConfigurableApplicationContext run(String... args) {

        ConfigurableApplicationContext context = null;
        configureHeadlessProperty();
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.started();
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                    args);
            ConfigurableEnvironment environment = prepareEnvironment(listeners,
                    applicationArguments);
            Banner printedBanner = printBanner(environment);
            context = createApplicationContext();
            analyzers = new FailureAnalyzers(context);
            prepareContext(context, environment, listeners, applicationArguments,
                    printedBanner);
            listeners.finished(context, null);
            return context;
        }
        catch (Throwable ex) {
            handleRunFailure(context, listeners, analyzers, ex);
            throw new IllegalStateException(ex);
        }
    }

它首先開啟一個(gè)SpringApplicationRunListeners監(jiān)聽器,然后創(chuàng)建一個(gè)應(yīng)用上下文ConfigurableApplicationContext,通過(guò)這個(gè)上下文加載應(yīng)用所需的類和各種環(huán)境配置等。

一個(gè)應(yīng)用能夠正常運(yùn)行起來(lái),需要一些環(huán)境變量、各種資源和一些相關(guān)配置等,下面看下createApplicationContext方法會(huì)加載應(yīng)用定義的和需要的類及各種資源。

自動(dòng)配置

所有的自動(dòng)配置都是從注解@SpringBootApplication引入的,它其實(shí)又包含了@Configuration、@EnableAutoConfiguration和@ComponentScan,其中,@EnableAutoConfiguration就是啟用自動(dòng)配置的,并將導(dǎo)入一些自動(dòng)配置的類定義。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
    Class<?>[] exclude() default {};
    String[] excludeName() default {};
    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackages"
    )
    String[] scanBasePackages() default {};
    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackageClasses"
    )
    Class<?>[] scanBasePackageClasses() default {};
}

EnableAutoConfiguration最終會(huì)導(dǎo)入一個(gè)自動(dòng)配置的類列表,列表中的自動(dòng)配置類很多,這些配置類中大都將被導(dǎo)入,并處于備用狀態(tài),當(dāng)項(xiàng)目中引入了相關(guān)的包時(shí),相關(guān)的功能將被啟用。

例如在項(xiàng)目的maven配置中配置了Redis的引用,Redis的默認(rèn)配置項(xiàng)將被啟用,首先會(huì)讀取項(xiàng)目中的配置,只有項(xiàng)目中沒有相關(guān)配置才啟用配置的默認(rèn)值,下面代碼是Redis的自動(dòng)配置,如果配置文件中沒設(shè)置,會(huì)使用下面默認(rèn)設(shè)置。

@ConfigurationProperties(
    prefix = "spring.redis"
)
public class RedisProperties {
    private int database = 0;
    private String host = "localhost";
    private String password;
    private int port = 6379;
    private int timeout;
    private RedisProperties.Pool pool;
    private RedisProperties.Sentinel sentinel;
    private RedisProperties.Cluster cluster;

    public RedisProperties() {
    }

通過(guò)自動(dòng)配置,就不用重復(fù)定義配置項(xiàng)名稱了,覆蓋約定的配置項(xiàng)即可。可通過(guò)查看各個(gè)Properties類,查看有哪些配置項(xiàng)。

Spring Boot數(shù)據(jù)訪問實(shí)現(xiàn)原理

要使用數(shù)據(jù)庫(kù),首先必須與數(shù)據(jù)庫(kù)服務(wù)器建立連接。對(duì)于關(guān)系型數(shù)據(jù)庫(kù),Spring Boot 連接數(shù)據(jù)源一般都采用JDBC的方式來(lái)實(shí)現(xiàn)。其他類型的數(shù)據(jù)庫(kù)使用各自獨(dú)立的方式來(lái)建立連接。

數(shù)據(jù)源類型和驅(qū)動(dòng)

JDBC連接數(shù)據(jù)源必須指定數(shù)據(jù)源類型和數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序,數(shù)據(jù)源主要有4中:

  • 使用java.sql.DriverManager類;
  • 使用實(shí)現(xiàn)了javax.sql.DataSource接口的子類,DataSource接口由驅(qū)動(dòng)程序供應(yīng)商實(shí)現(xiàn),主要有3類實(shí)現(xiàn)、基本實(shí)現(xiàn)、連接池實(shí)現(xiàn),分布式事務(wù)實(shí)現(xiàn) ;
  • DBCP連接池,Apache 軟件基金組織下的開源連接池實(shí)現(xiàn),Tomcat 的連接池正是采用該連接池來(lái)實(shí)現(xiàn)的;
  • C3P0連接池;

Spring Boot 默認(rèn)使用org.apache.tomcat.jdbc.pool.DataSource,它使用第2種方式,實(shí)現(xiàn)了javax.sql.DataSource接口。數(shù)據(jù)源的類型可以通過(guò)配置更改。

另外,Spring Boot 默認(rèn)幾乎支持現(xiàn)有的所有數(shù)據(jù)庫(kù)。

數(shù)據(jù)存取功能實(shí)現(xiàn)

與數(shù)據(jù)庫(kù)建立連接后,就可以對(duì)數(shù)據(jù)庫(kù)執(zhí)行一些存取操作,對(duì)數(shù)據(jù)庫(kù)實(shí)現(xiàn)管理的功能。數(shù)據(jù)存取操作大體上包含兩方面的內(nèi)容,即實(shí)體建模和持久化。

不管是關(guān)系型數(shù)據(jù)庫(kù),還是NoSQL數(shù)據(jù)庫(kù),都遵循這一設(shè)計(jì)規(guī)范。實(shí)體建模即將Java的普通對(duì)象和關(guān)系映射為數(shù)據(jù)庫(kù)表機(jī)器相關(guān)的關(guān)系,在Spring Boot中,主要是通過(guò)注解實(shí)現(xiàn)。

關(guān)系型數(shù)據(jù)庫(kù)都使用了JPA的一套標(biāo)準(zhǔn),它結(jié)合使用Hibernate實(shí)現(xiàn)了實(shí)體的持久化。后續(xù)的數(shù)據(jù)庫(kù)管理設(shè)計(jì)都遵循了JPA這一個(gè)標(biāo)準(zhǔn)規(guī)范,提供相同的訪問數(shù)據(jù)庫(kù)的API。

微服務(wù)核心技術(shù)實(shí)現(xiàn)原理

Spring Cloud是基于對(duì)Netfix開源組件進(jìn)一步封裝的一套云應(yīng)用開發(fā)工具,可以用來(lái)開發(fā)各種微服務(wù)應(yīng)用。

配置服務(wù)實(shí)現(xiàn)

前一篇文章說(shuō)到,配置管理的在線更新功能使用事件總線,即spring-cloud-bus來(lái)發(fā)布狀態(tài)變化,并使用分布式消息來(lái)發(fā)布更新事件,分布式消息最終使用RabbitMQ來(lái)實(shí)現(xiàn)消息收發(fā)。

再來(lái)回顧下在線更新流程:

  • 更新Git倉(cāng)庫(kù)的配置文件;
  • 以POST指令出發(fā)更新請(qǐng)求;
  • 配置管理服務(wù)器從Git倉(cāng)庫(kù)中讀取配置文件,并將配置文件分發(fā)給各個(gè)客戶端,同時(shí)在RabbitMQ中發(fā)布一個(gè)更新消息;
  • 客戶端訂閱RabbitMQ消息,收到消息后執(zhí)行更新;

配置管理服務(wù)器中的消息分發(fā)是從spring-cloud-bus中調(diào)用spring-cloud-stream組件實(shí)現(xiàn)的,而spring-cloud-stream使用RabbitMQ實(shí)現(xiàn)了分布式消息分發(fā)。具體實(shí)現(xiàn)就不說(shuō)了,使用過(guò)RabbitMQ的很好理解。

發(fā)現(xiàn)服務(wù)和負(fù)載均衡

客戶端執(zhí)行注冊(cè)使用計(jì)劃任務(wù)的方式來(lái)實(shí)現(xiàn),而客戶端從發(fā)現(xiàn)服務(wù)器中更新其他在線的客戶端列表,也使用了一個(gè)定時(shí)任務(wù)來(lái)管理。

當(dāng)一個(gè)應(yīng)用啟用發(fā)現(xiàn)服務(wù)的功能之后,會(huì)默認(rèn)啟用Ribbon的負(fù)載均衡服務(wù)。Ribbon通過(guò)發(fā)現(xiàn)服務(wù)獲取在線的客戶端,為具有多個(gè)實(shí)例的客戶端建立起負(fù)載均衡管理機(jī)制。

分布式消息實(shí)現(xiàn)

使用spirng-cloud-stream可以非常簡(jiǎn)單地使用RabbitMQ的異步消息,Spring Cloud的配置管理中的分布式消息分發(fā)也是通過(guò)調(diào)用spring-cloud-stream組件來(lái)實(shí)現(xiàn)的。

下面以消息生產(chǎn)者和消費(fèi)者的實(shí)現(xiàn)說(shuō)明分布式消息實(shí)現(xiàn)

消息生產(chǎn)者:

@EnableBinding(Source.class)
@RestController 
@SpringBootApplication 
public class SenderApplication { 
    @Autowired 
    @Output(Source.OUTPUT) 
    private MessageChannel channel;

    @RequestMapping(method = RequestMethod.POST, path = "/send") 
    public void write (@RequestBody Map<String, Object> msg){
        channel.send(MessageBuilder.withPayload(msg).build());
    } 

    public static void main(String[] args) {
        SpringApplication.run(SenderApplication.class, args);
    } 
}

消息消費(fèi)者:

@EnableBinding(Sink.class)
@IntegrationComponentScan
@MessageEndpoint
@SpringBootApplication
public class ReceiverApplication {
    @ServiceActivator(inputChannel=Sink.INPUT)
    public void accept(Map<String, Object> msg){
        System.out.println(msg.get("msg").toString() + ":" + msg.get("name"));
    }

    public static void main(String[] args) {
        SpringApplication.run(ReceiverApplication.class, args);
    }
}

從上面的分析可以看到,Spring Boot及其一些相關(guān)組件,已經(jīng)盡量把一些可以實(shí)現(xiàn)和做到的功能,都幫我們實(shí)現(xiàn)了。 雖然使用Spring Boot及其相關(guān)組件看起來(lái)非常簡(jiǎn)單,但實(shí)際上可以實(shí)現(xiàn)無(wú)比強(qiáng)大的功能,這就是Spring Boot 及其組件的神奇所在。

《深入實(shí)踐Spring Boot》閱讀筆記之三:核心技術(shù)源代碼分析

創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國(guó)云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開啟,新人活動(dòng)云服務(wù)器買多久送多久。

當(dāng)前標(biāo)題:《深入實(shí)踐SpringBoot》閱讀筆記之三:核心技術(shù)源代碼分析-創(chuàng)新互聯(lián)
文章起源:http://muchs.cn/article20/csggjo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、定制網(wǎng)站企業(yè)建站、軟件開發(fā)、網(wǎng)站收錄、App開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)