Spring Boot快速上手
Spring Boot簡介
Spring Boot是由Pivotal團隊提供的全新框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程。有了它,你可以更加敏捷地開發Spring應用程式,專注於應用程式的功能,而不用在Spring的配置上多花功夫,甚至完全不用配置。
Spring Boot提供了四個核心功能:
- 自動配置:針對很多Spring應用程式的常見的應用功能,Spring Boot能自動提供相關的配置;
- 起步依賴:告訴Spring Boot需要什麼功能,它就能引入需要的庫;
- Spring Boot CLI:你只需寫程式碼就能完成完整的應用程式,無需傳統專案構建;
- Actuator:讓你深入執行中的Spring Boot應用程式,一探究竟。
每一個特性都能以自己的方式簡化Spring應用的開發。
首先,我們看一下如何開發一個Spring Boot的Hello World程式。
Spring Boot工程搭建
Spring Boot工程與普通的maven/gradle工程無異,只是在依賴中需要新增對Spring Boot的依賴。不過,有一種更簡單的方式是直接用Spring官網的Spring Initializer來生成專案骨架。
開啟:https://start.spring.io/,填寫工程型別、語言、Spring Boot版本號及構件資訊,如下圖:
點選Generate Project後,會自動下載完整的專案骨架下來,並且在pom.xml中已經幫你依賴好了所需依賴的構件。
pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>demo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
同時可以看到主類DemoApplication.java:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
執行該類,看到如下輸出即為啟動成功:
至此,我們便完成了一個最簡專案的搭建和執行。
Spring Boot應用的啟動流程
DemoApplication類在我們的Spring Boot應用中有兩個作用:配置和啟動引導。
我們可以看到在主類上,有一個@SpringBootApplication註解,這個註解開啟了Spring的元件掃描和Spring Boot的自動配置功能,檢視其原始碼:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.springframework.boot.autoconfigure;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.core.annotation.AliasFor;
@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 {
@AliasFor(
annotation = EnableAutoConfiguration.class
)
Class<?>[] exclude() default {};
@AliasFor(
annotation = EnableAutoConfiguration.class
)
String[] excludeName() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackages"
)
String[] scanBasePackages() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackageClasses"
)
Class<?>[] scanBasePackageClasses() default {};
}
可以看到它是把Spring的@Configuration、Spring的@ComponentScan和Spring Boot的@EnableAutoConfiguration組合到了一起。
Spring Boot起步依賴
在傳統的Spring應用中,使用某個特定的功能時,需要自己手動新增對應的依賴,不僅麻煩,而且容易因為不同構件版本之間的相容問題而出錯。
Spring Boot提供了眾多的起步依賴,降低專案依賴的複雜度。起步依賴本質上是一個Maven專案物件模型,定義了對其他庫的傳遞依賴,這些東西加在一起即支援某項功能。
在上面的例子中,期望開發一個Web應用,我們依賴了spring-boot-starter-web,由它去依賴其他的構件。
Spring Boot自動配置
Spring Boot自動配置是一個執行時(更準確地說,是應用程式啟動時)的過程,考慮了眾多因素,才決定Spring配置應該用哪個,不該用哪個。
例如:Spring的JdbcTemplate是不是在Classpath下?如果是,並且有DataSource Bean,那麼就自動配置一個JdbcTemplate的Bean等等。
自動配置的原理是利用了Spring4.0引入的條件化配置的特性,條件化配置允許配置存在於應用程式中,但在滿足特定的條件之前都忽略這些配置。
以Spring Boot下的國際化為例,其自動配置類在org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration類中。大致原始碼如下:
package org.springframework.boot.autoconfigure.context;
@Configuration
@ConditionalOnMissingBean(
value = {MessageSource.class},
search = SearchStrategy.CURRENT
)
@AutoConfigureOrder(-2147483648)
@Conditional({MessageSourceAutoConfiguration.ResourceBundleCondition.class})
@EnableConfigurationProperties
public class MessageSourceAutoConfiguration {
private static final Resource[] NO_RESOURCES = new Resource[0];
public MessageSourceAutoConfiguration() {
}
@Bean
@ConfigurationProperties(
prefix = "spring.messages"
)
public MessageSourceProperties messageSourceProperties() {
return new MessageSourceProperties();
}
@Bean
public MessageSource messageSource(MessageSourceProperties properties) {
...
可以看到這個配置類上使用了條件化註解@ConditionalOnMissingBean(value = MessageSource.class, search = SearchStrategy.CURRENT),表示在當前上下文中不存在MessageSource Bean時,這個配置類才生效。然後根據其messageSource(MessageSourceProperties)方法,自動建立一個MessageSource Bean。
Spring Boot應用的打包和執行
Spring Boot應用可以被打包成jar檔案直接執行,如果是Web應用,也可以打包成war包丟進傳統的應用伺服器(如Tomcat等)中執行。由於Spring Boot在應用程式裡嵌入了一個Servlet容器,所以Spring Boot開發的Web應用也可以打包成jar包直接執行,而不用部署到傳統的Java應用伺服器裡。
舉一個Spring Boot開發RESTful介面的例子:
在前面我們建立好的工程中,加入一個RestController如下:
package com.example.demo;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class DemoService {
@RequestMapping(method = RequestMethod.POST, path = "/rest/evaluate")
public Map<String, Object> query(@RequestBody Map<String, Object> params) {
Map<String, Object> obj = new HashMap<String, Object>(5) {
{
put("price", 19.25);
put("amount", 17891);
put("commodity", "iPhone X");
}
};
return obj;
}
}
然後我們對工程執行mvn clean package,打出jar包,然後通過java命令執行起該jar包,通過postman訪問本地8080埠:
可以訪問成功。
在我們的pom.xml中,可以看到使用了外掛spring-boot-maven-plugin,這個外掛的作用是在打jar包時打出一個超級jar,把應用程式所有依賴都打進這個jar中,同時為jar新增一個描述檔案,其中的內容能讓你用java -jar執行應用程式。我們開啟jar包的BOOT-INF/lib目錄,可以看到依賴的jar包都被打進來了:
至此,我們完成了對Spring Boot的一個概要的瞭解,掌握瞭如何建立Spring Boot應用,Spring Boot的核心特性以及如何打包部署執行Spring Boot程式。快去開發你的Spring Boot應用吧~~