前言:
這一篇需要spring boot和設計模式的基礎知識,從設計模式的角度先去談spring boot,再介紹spring boot的啓動流程以及環境注入的一些知識。學習過程中發現網上還是有很多坑的,這裏儘量統一做下總結。
fig.1
一,spring boot簡介
fig.2
spring boot中設計到的東西其實很繁雜,如果你學會了Java,並且可以用Java做一些簡單的工程,知道Java的多線程機制,JVM,關鍵字等等,說明你對Java SE以及有了基礎。而spring是Java EE的範疇,也就是說,使用Spring框架一般可以作爲真正商業可用的應用程序開發,而且大多數公司確實也是用spring框架來實現Java的商業性應用開發。
至於Spring全家桶都有哪些需要你自己去了解,因爲涉及到的東西真的很多,這裏只講這套spring boot開發框架中最基礎的東西。
什麼是Spring Boot?
spring Boot設計目的是用來簡化新Spring應用的初始搭建以及開發過程。該框架集合之前的spring框架,使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。也就是說,我可以只需要非常少的幾個配置就可以迅速方便的搭建起來一套web項目或者是構建一個微服務。
我的意見是,和gRPC類似,spring Boot也是一個要學習怎麼去用,不要學習如何去改的框架。首先spring boot運行涉及的概念很明確,不過理解也很繁瑣。關於bean,IOC,DI,AOP,註解以及POJO一些spring boot框架開發的概念需要吃透並理解,才能在使用的時候更好理解自己的工程,然後去使用。
二,工廠設計模式與spring boot
Spring使用工廠模式可以通過 BeanFactory 或 ApplicationContext 創建 bean 對象。
BeanFactory :延遲注入(使用到某個 bean 的時候纔會注入), 相比於ApplicationContext 來說會佔用更少的內存,程序啓動速度更快。
ApplicationContext :容器啓動的時候,不管你用沒用到,一次性創建所有 bean 。BeanFactory 僅提供了最基本的依賴注入支持,ApplicationContext 擴展了 BeanFactory ,除了有BeanFactory的功能還有額外更多功能,所以一般開發人員使用ApplicationContext會更多。
什麼是上下文?
"context是environment的snapshot."
每一段程序都有很多外部變量。只有像Add這種簡單的函數纔是沒有外部變量的。一旦你的一段程序有了外部變量,這段程序就不完整,不能獨立運行。你爲了使他們運行,就要給所有的外部變量一個一個寫一些值進去。這些值的集合就叫上下文。
Application Context的實現類
ApplicationContext的三個實現類:
ClassPathXmlApplication:把上下文文件當成類路徑資源。
FileSystemXmlApplication:從文件系統中的 XML 文件載入上下文定義信息。
XmlWebApplicationContext:從Web系統中的XML文件載入上下文定義信息。
當以上實現類一般不會在你的工程中用到,spring啓動的時候會根據實現注入我們所需要的配置來運行我們想要的工程。
三,觀察者模式與spring boot
什麼是觀察者模式?
當一個對象(目標對象)的狀態發生改變,所有的依賴對象(觀察者對象)都將得到通知,進行廣播通知。用來使用面向對象技術,將這種依賴關係弱化。
觀察者模式是一種對象行爲型模式。它表示的是一種對象與對象之間具有依賴關係,當一個對象發生改變的時候,這個對象所依賴的對象也會做出反應。Spring 事件驅動模型就是觀察者模式很經典的一個應用。Spring 事件驅動模型非常有用,在很多場景都可以解耦我們的代碼。比如我們每次添加商品的時候都需要重新更新商品索引,這個時候就可以利用觀察者模式來解決這個問題。
Spring事件驅動角色
事件角色
定義一個事件: 實現一個繼承自 ApplicationEvent,並且寫相應的構造函數;具體spring boot中定義的事件如圖
fig.3
事件監聽者角色
ApplicationListener 充當了事件監聽者角色,它是一個接口,裏面只定義了一個 onApplicationEvent()方法來處理ApplicationEvent
事件發佈者角色
使用事件發佈者發佈消息: 可以通過 ApplicationEventPublisher 的 publishEvent() 方法發佈消息
Spring事件流程總結
在run的情況下攜帶上下文運行,然後創建不同的listener去監聽事件完成應用的初始化,
在run的時候spring創建並幫助應用程序啓動,
1.獲取創建listener (starting)
2.創建參數。配置environment(envPrepared)
3.創建applicationContext
4.初始化上下文(contextPrepared),加載配置(contextLoaded)
5.更新上下文(Started),啓動程序(running)
四,spring boot env環境注入
Spring Boot可以外部化配置,以便可以在不同環境中使用相同的應用程序代碼。你可以使用屬性文件,YAML文件,環境變量和命令行參數來外部化配置,可以使用@Value批註將屬性值直接注入到您的bean中,可以通過Spring的Environment抽象訪問,也可以通過@ConfigurationProperties綁定到結構化對象。
Spring Boot使用一個非常特殊的PropertySource順序,該順序旨在允許合理地覆蓋值。按以下順序考慮屬性:
https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#boot-features-command-line-runner
1.Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
2.@TestPropertySource annotations on your tests.
3.properties attribute on your tests. Available on @SpringBootTest and the test annotations for testing a particular slice of your application.
4.Command line arguments.
5.Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).
6.ServletConfig init parameters.
7.ServletContext init parameters.
8.JNDI attributes from java:comp/env.
9.Java System properties (System.getProperties()).
10.OS environment variables.
11.A RandomValuePropertySource that has properties only in random.*.
12.Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants).
13.Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants).
14.Application properties outside of your packaged jar (application.properties and YAML variants).
15.Application properties packaged inside your jar (application.properties and YAML variants).
16.@PropertySource annotations on your @Configuration classes.
17.Default properties (specified by setting SpringApplication.setDefaultProperties).
To provide a concrete example, suppose you develop a @Component that uses a name property, as shown in the following
@TestPropertySource用法:
@TestPropertySource註解用於springboot項目測試的env配置注入,通過可選元素可以覆蓋掉test自身讀到的配置文件
可選元素主要有兩個:
string[] locations //指定配置的路徑
string[] properties //指定配置的屬性
properties的優先級大於locations
舉例:
@TestPropertySource(properties = "guardian.server.access.token.admin.perm.enabled=true")
.properties//.yaml
@PropertySource
參考:
1. https://www.ibm.com/developerworks/cn/java/j-lo-spring-boot/index.html#listing4
2. http://www.throwable.club/2018/12/16/spring-boot-environment-configuration-spread/
3. https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#boot-features-command-line-runner