您好,登錄后才能下訂單哦!
剛關注的朋友,可以回顧前兩篇文章:
上篇文章總結了《深入實踐Spring Boot》的第二部分,本篇文章總結第三部分,也是最后一部分。這部分主要講解核心技術的源代碼分析,因為篇幅和能力原因,分析的不會太詳細,后續深入研究后再專門寫文章。希望大家能從「閱讀筆記」3篇文章中,對Spring Boot提供的功能有所了解,在項目中進行實踐,不斷從繁瑣重復的開發中解放出來。
我也是最近剛開始了解Spring Boot,計劃今年在項目中實踐,到時會總結實踐過程中的一些問題和經驗,分享給大家。想一起學習、實踐、交流的朋友,可以掃描文章下方的二維碼,關注我的個人公眾號,感謝大家。
本篇主要從以下幾個方面總結:
春節假期很快過去了,明天就要上班了,相信大家還是意猶未盡,沒吃夠、沒玩夠、沒和家人待夠。今年因為個人原因,沒有回家過年,心理最牽掛的還是爺爺奶奶,他們都80多了,希望她們身體健康,開開心心地度過生命最后的旅程。
不管怎樣,大家要切換頻道了,回歸到正常的工作中,好好努力,一起期待明年和家人更好的團聚。
使用Spring Boot創建一個簡單的Web項目很簡潔,不需要太多配置,編寫一個簡單的主程序就行:
@SpringBootApplication
public class ConfigApplication{
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
首先分析下run方法(省略不關鍵的部分代碼):
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);
}
}
它首先開啟一個SpringApplicationRunListeners監聽器,然后創建一個應用上下文ConfigurableApplicationContext,通過這個上下文加載應用所需的類和各種環境配置等。
一個應用能夠正常運行起來,需要一些環境變量、各種資源和一些相關配置等,下面看下createApplicationContext方法會加載應用定義的和需要的類及各種資源。
所有的自動配置都是從注解@SpringBootApplication引入的,它其實又包含了@Configuration、@EnableAutoConfiguration和@ComponentScan,其中,@EnableAutoConfiguration就是啟用自動配置的,并將導入一些自動配置的類定義。
@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最終會導入一個自動配置的類列表,列表中的自動配置類很多,這些配置類中大都將被導入,并處于備用狀態,當項目中引入了相關的包時,相關的功能將被啟用。
例如在項目的maven配置中配置了Redis的引用,Redis的默認配置項將被啟用,首先會讀取項目中的配置,只有項目中沒有相關配置才啟用配置的默認值,下面代碼是Redis的自動配置,如果配置文件中沒設置,會使用下面默認設置。
@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() {
}
通過自動配置,就不用重復定義配置項名稱了,覆蓋約定的配置項即可。可通過查看各個Properties類,查看有哪些配置項。
要使用數據庫,首先必須與數據庫服務器建立連接。對于關系型數據庫,Spring Boot 連接數據源一般都采用JDBC的方式來實現。其他類型的數據庫使用各自獨立的方式來建立連接。
JDBC連接數據源必須指定數據源類型和數據庫驅動程序,數據源主要有4中:
Spring Boot 默認使用org.apache.tomcat.jdbc.pool.DataSource,它使用第2種方式,實現了javax.sql.DataSource接口。數據源的類型可以通過配置更改。
另外,Spring Boot 默認幾乎支持現有的所有數據庫。
與數據庫建立連接后,就可以對數據庫執行一些存取操作,對數據庫實現管理的功能。數據存取操作大體上包含兩方面的內容,即實體建模和持久化。
不管是關系型數據庫,還是NoSQL數據庫,都遵循這一設計規范。實體建模即將Java的普通對象和關系映射為數據庫表機器相關的關系,在Spring Boot中,主要是通過注解實現。
關系型數據庫都使用了JPA的一套標準,它結合使用Hibernate實現了實體的持久化。后續的數據庫管理設計都遵循了JPA這一個標準規范,提供相同的訪問數據庫的API。
Spring Cloud是基于對Netfix開源組件進一步封裝的一套云應用開發工具,可以用來開發各種微服務應用。
前一篇文章說到,配置管理的在線更新功能使用事件總線,即spring-cloud-bus來發布狀態變化,并使用分布式消息來發布更新事件,分布式消息最終使用RabbitMQ來實現消息收發。
再來回顧下在線更新流程:
配置管理服務器中的消息分發是從spring-cloud-bus中調用spring-cloud-stream組件實現的,而spring-cloud-stream使用RabbitMQ實現了分布式消息分發。具體實現就不說了,使用過RabbitMQ的很好理解。
客戶端執行注冊使用計劃任務的方式來實現,而客戶端從發現服務器中更新其他在線的客戶端列表,也使用了一個定時任務來管理。
當一個應用啟用發現服務的功能之后,會默認啟用Ribbon的負載均衡服務。Ribbon通過發現服務獲取在線的客戶端,為具有多個實例的客戶端建立起負載均衡管理機制。
使用spirng-cloud-stream可以非常簡單地使用RabbitMQ的異步消息,Spring Cloud的配置管理中的分布式消息分發也是通過調用spring-cloud-stream組件來實現的。
下面以消息生產者和消費者的實現說明分布式消息實現
消息生產者:
@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);
}
}
消息消費者:
@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及其一些相關組件,已經盡量把一些可以實現和做到的功能,都幫我們實現了。 雖然使用Spring Boot及其相關組件看起來非常簡單,但實際上可以實現無比強大的功能,這就是Spring Boot 及其組件的神奇所在。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。