Spring Boot 入門之基礎篇(一)

1、前言

Spring Boot 是由 Pivotal 團隊提供的全新框架,其設計目的是用來簡化新 Spring 應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員再也不須要定義樣板化的配置。css

本系列以快速入門爲主,可看成工具小手冊閱讀html

2、環境搭建

建立一個 maven 工程,目錄結構以下圖:java

imageimagemysql

2.1 添加依賴

建立 maven 工程,在 pom.xml 文件中添加以下依賴:web

 

1spring

2sql

3瀏覽器

4tomcat

5springboot

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

 

<!-- 定義公共資源版本 -->

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>1.5.6.RELEASE</version>

<relativePath />

</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>

<!-- 上邊引入 parent,所以 下邊無需指定版本 -->

<!-- 包含 mvc,aop 等jar資源 -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

</dependencies>

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

</plugins>

</build>

2.2 建立目錄和配置文件

建立 src/main/resources 源文件目錄,並在該目錄下建立 application.properties 文件、static 和 templates 的文件夾。

application.properties:用於配置項目運行所需的配置數據。

static:用於存放靜態資源,如:css、js、圖片等。

templates:用於存放模板文件。

目錄結構以下:

imageimage

2.3 建立啓動類

在 com.light.springboot 包下建立啓動類,以下:

 

1

2

3

4

5

6

7

8

9

10

11

12

 

/**

該註解指定項目爲springboot,由此類看成程序入口

自動裝配 web 依賴的環境

**/

@SpringBootApplication

public class SpringbootApplication {

public static void main(String[] args) {

SpringApplication.run(SpringbootApplication.class, args);

}

}

2.4 案例演示

建立 com.light.springboot.controller 包,在該包下建立一個 Controller 類,以下:

 

1

2

3

4

5

6

7

8

 

@RestController

public class TestController {

@GetMapping("/helloworld")

public String helloworld() {

return "helloworld";

}

}

在 SpringbootApplication 文件中右鍵 Run as -> Java Application。當看到 「Tomcat started on port(s): 8080 (http)」 字樣說明啓動成功。

打開瀏覽器訪問 http://localhost:8080/helloworld,結果以下:

imageimage

讀者可使用 STS 開發工具,裏邊集成了插件,能夠直接建立 Spingboot 項目,它會自動生成必要的目錄結構。

3、熱部署

當咱們修改文件和建立文件時,都須要從新啓動項目。這樣頻繁的操做很浪費時間,配置熱部署可讓項目自動加載變化的文件,省去的手動操做。

在 pom.xml 文件中添加以下配置:

 

1

2

3

4

5

6

7

 

<!-- 熱部署 -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-devtools</artifactId>

<optional>true</optional>

<scope>true</scope>

</dependency>

 

1

2

3

4

5

6

7

8

9

10

11

12

 

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

<configuration>

<!-- 沒有該配置,devtools 不生效 -->

<fork>true</fork>

</configuration>

</plugin>

</plugins>

</build>

配置好 pom.xml 文件後,咱們啓動項目,隨便建立/修改一個文件並保存,會發現控制檯打印 springboot 從新加載文件的信息。

演示圖以下:

imageimage

4、多環境切換

application.properties 是 springboot 在運行中所須要的配置信息。

當咱們在開發階段,使用本身的機器開發,測試的時候須要用的測試服務器測試,上線時使用正式環境的服務器。

這三種環境須要的配置信息都不同,當咱們切換環境運行項目時,須要手動的修改多出配置信息,很是容易出錯。

爲了解決上述問題,springboot 提供多環境配置的機制,讓開發者很是容易的根據需求而切換不一樣的配置環境。

在 src/main/resources 目錄下建立三個配置文件:

 

1

2

3

 

application-dev.properties:用於開發環境

application-test.properties:用於測試環境

application-prod.properties:用於生產環境

咱們能夠在這個三個配置文件中設置不一樣的信息,application.properties 配置公共的信息。

在 application.properties 中配置:

 

1

 

spring.profiles.active=dev

表示激活 application-dev.properties 文件配置, springboot 會加載使用 application.properties 和 application-dev.properties 配置文件的信息。

同理,可將 spring.profiles.active 的值修改爲 test 或 prod 達到切換環境的目的。

演示圖以下:

imageimage

切換項目啓動的環境不只對讀取配置文件信息有效,也能夠對 Bean 有效。

當咱們須要對不一樣環境使用不一樣的 Bean 時,能夠經過 @Profile 註解進行區分,以下:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

 

@Configuration

public class BeanConfiguration {

@Bean

@Profile("dev")

public Runnable test1() {

System.out.println("開發環境使用的 Bean");

return () -> {};

}

@Bean

@Profile("test")

public Runnable test2() {

System.out.println("測試環境使用的 Bean");

return () -> {};

}

@Bean

@Profile("pro")

public Runnable test3() {

System.out.println("生成環境使用的 Bean");

return () -> {};

}

}

當啓動項目後,Spring 會根據 spring.profiles.active 的值實例化對應的 Bean。

5、配置日誌

5.1 配置 logback(官方推薦使用)

5.1.1 配置日誌文件

spring boot 默認會加載 classpath:logback-spring.xml 或者 classpath:logback-spring.groovy。

如須要自定義文件名稱,在 application.properties 中配置 logging.config 選項便可。

在 src/main/resources 下建立 logback-spring.xml 文件,內容以下:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

 

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

<!-- 文件輸出格式 -->

<property name="PATTERN" value="%-12(%d{yyyy-MM-dd HH:mm:ss.SSS}) |-%-5level [%thread] %c [%L] -| %msg%n" />

<!-- test文件路徑 -->

<property name="TEST_FILE_PATH" value="d:/test.log" />

<!-- pro文件路徑 -->

<property name="PRO_FILE_PATH" value="/opt/test/log" />

<!-- 開發環境 -->

<springProfile name="dev">

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">

<encoder>

<pattern>${PATTERN}</pattern>

</encoder>

</appender>

<logger name="com.light.springboot" level="debug" />

<root level="info">

<appender-ref ref="CONSOLE" />

</root>

</springProfile>

<!-- 測試環境 -->

<springProfile name="test">

<!-- 天天產生一個文件 -->

<appender name="TEST-FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">

<!-- 文件路徑 -->

<file>${TEST_FILE_PATH}</file>

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

<!-- 文件名稱 -->

<fileNamePattern>${TEST_FILE_PATH}/info.%d{yyyy-MM-dd}.log</fileNamePattern>

<!-- 文件最大保存歷史數量 -->

<MaxHistory>100</MaxHistory>

</rollingPolicy>

<layout class="ch.qos.logback.classic.PatternLayout">

<pattern>${PATTERN}</pattern>

</layout>

</appender>

<logger name="com.light.springboot" level="debug" />

<root level="info">

<appender-ref ref="TEST-FILE" />

</root>

</springProfile>

<!-- 生產環境 -->

<springProfile name="prod">

<appender name="PROD_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">

<file>${PRO_FILE_PATH}</file>

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

<fileNamePattern>${PRO_FILE_PATH}/warn.%d{yyyy-MM-dd}.log</fileNamePattern>

<MaxHistory>100</MaxHistory>

</rollingPolicy>

<layout class="ch.qos.logback.classic.PatternLayout">

<pattern>${PATTERN}</pattern>

</layout>

</appender>

<root level="warn">

<appender-ref ref="PROD_FILE" />

</root>

</springProfile>

</configuration>

其中,springProfile 標籤的 name 屬性對應 application.properties 中的 spring.profiles.active 的配置。

即 spring.profiles.active 的值能夠看做是日誌配置文件中對應的 springProfile 是否生效的開關。

5.2 配置 log4j2

5.2.1 添加依賴

 

1

2

3

4

 

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-log4j2</artifactId>

</dependency>

5.2.2 配置日誌文件

spring boot 默認會加載 classpath:log4j2.xml 或者 classpath:log4j2-spring.xml。

如須要自定義文件名稱,在 application.properties 中配置 logging.config 選項便可。

log4j2.xml 文件內容以下:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

 

<?xml version="1.0" encoding="utf-8"?>

<configuration>

<properties>

<!-- 文件輸出格式 -->

<property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} |-%-5level [%thread] %c [%L] -| %msg%n</property>

</properties>

<appenders>

<Console name="CONSOLE" target="system_out">

<PatternLayout pattern="${PATTERN}" />

</Console>

</appenders>

<loggers>

<logger name="com.light.springboot" level="debug" />

<root level="info">

<appenderref ref="CONSOLE" />

</root>

</loggers>

</configuration>

log4j2 不能像 logback 那樣在一個文件中設置多個環境的配置數據,只能命名 3 個不一樣名的日誌文件,分別在 application-dev,application-test 和 application-prod 中配置 logging.config 選項。

除了在日誌配置文件中設置參數以外,還能夠在 application-*.properties 中設置,日誌相關的配置:

 

1

2

3

4

5

6

7

8

9

 

logging.config # 日誌配置文件路徑,如 classpath:logback-spring.xml

logging.exception-conversion-word # 記錄異常時使用的轉換詞

logging.file # 記錄日誌的文件名稱,如:test.log

logging.level.* # 日誌映射,如:logging.level.root=WARN,logging.level.org.springframework.web=DEBUG

logging.path # 記錄日誌的文件路徑,如:d:/

logging.pattern.console # 向控制檯輸出的日誌格式,只支持默認的 logback 設置。

logging.pattern.file # 向記錄日誌文件輸出的日誌格式,只支持默認的 logback 設置。

logging.pattern.level # 用於呈現日誌級別的格式,只支持默認的 logback 設置。

logging.register-shutdown-hook # 初始化時爲日誌系統註冊一個關閉鉤子

6、註解介紹

下面列出 Spring Boot 開發中經常使用的註解:

 

1

2

3

4

5

6

7

8

9

10

11

 

@Configuration # 做用於類上,至關於一個 xml 配置文件

@Bean # 做用於方法上,至關於 xml 配置中的 <bean>

@SpringBootApplication # Spring Boot的核心註解,是一個組合註解,用於啓動類上

@EnableAutoConfiguration # 啓用自動配置,容許加載第三方 Jar 包的配置

@ComponentScan # 默認掃描 @SpringBootApplication 所在類的同級目錄以及它的子目錄

@PropertySource # 加載 properties 文件

@Value # 將配置文件的屬性注入到 Bean 中特定的成員變量

@EnableConfigurationProperties # 開啓一個特性,讓配置文件的屬性能夠注入到 Bean 中,與 @ConfigurationProperties 結合使用

@ConfigurationProperties # 關聯配置文件中的屬性到 Bean 中

@Import # 加載指定 Class 文件,其生命週期被 Spring 管理

@ImportResource # 加載 xml 文件

傳統項目下使用的註解,此處就再也不累述。

7、讀取配置文件

7.1 屬性裝配

有兩種方式:使用 @Value 註解和 Environment 對象。

在 application.properties 中添加:

 

1

2

3

4

 

ds.userName=root

ds.password=tiger

ds.url=jdbc:mysql://localhost:3306/test

ds.driverClassName=com.mysql.jdbc.Driver

以上是自定義的配置。

建立一個配置類,以下:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

 

@Configuration

public class WebConfig {

@Value("${ds.userName}")

private String userName;

@Autowired

private Environment environment;

public void show() {

System.out.println("ds.userName:" + this.userName);

System.out.println("ds.password:" + this.environment.getProperty("ds.password"));

}

}

經過 @Value 獲取 config.userName 配置;經過 environment 獲取 config.password 配置。

測試:

 

1

2

3

4

5

6

7

8

 

@SpringBootApplication

public class SpringbootApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootApplication.class, args);

context.getBean(WebConfig.class).show();

}

}

打印結果:

 

1

2

 

userName:root

password:tiger

7.2 對象裝配

建立一個封裝類:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

 

@Component

@ConfigurationProperties(prefix="ds")

public class DataSourceProperties {

private String url;

private String driverClassName;

private String userName;

private String password;

public void show() {

System.out.println("ds.url=" + this.url);

System.out.println("ds.driverClassName=" + this.driverClassName);

System.out.println("ds.userName=" + this.userName);

System.out.println("ds.password=" +this.password);

}

}

此處省略 setter 和 getter 方法。

測試:

 

1

2

3

4

5

6

7

8

 

@SpringBootApplication

public class SpringbootApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootApplication.class, args);

context.getBean(DataSourceProperties.class).show();

}

}

打印結果:

 

1

2

3

4

 

ds.url=jdbc:mysql://localhost:3306/test

ds.driverClassName=com.mysql.jdbc.Driver

ds.userName=root

ds.password=tiger

8、自動配置

在上文的例子中,咱們其實就使用到自動配置了,在此小結中再舉例說明,加深印象。

現有 2 個項目,一個 Maven 項目 和 Spring Boot 項目。

Spring Boot 項目引入 Maven 項目並使用 Maven 項目中寫好的類。

8.1 編碼

Maven 項目中的代碼:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

 

public class Cache {

private Map<String,Object> map = new HashMap<String,Object>();

public void set(String key,String value) {

this.map.put(key,value);

}

public Object get(String key) {

return this.map.get(key);

}

}

@Configuration

public class CacheConfirguration {

@Bean

public Cache createCacheObj() {

return new Cache();

}

}

Spring Boot 項目引入 Maven 項目:

pom.xml 文件:

 

1

2

3

4

5

 

<dependency>

<groupId>com.light</groupId>

<artifactId>cache</artifactId>

<version>0.0.1-SNAPSHOT</version>

</dependency>

測試:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

 

@SpringBootApplication

public class SpringbootApplication extends SpringBootServletInitializer {

@Override

protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {

return application.sources(SpringbootApplication.class);

}

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootApplication.class, args);

CacheConfirguration conf = context.getBean(CacheConfirguration.class);

System.out.println(conf);

Cache Cache = context.getBean(Cache.class);

System.out.println(Cache);

}

}

打印結果:

 

1

 

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.light.cache.Cache' available

從結果咱們可知 Spring Boot 並不會自動配置第三方 jar 資源文件。

由於 @SpringBootApplication 註解包含 @ComponentScan 註解,項目啓動時 Spring 只掃描與 SpringbootApplication 類同目錄和子目錄下的類文件,引入第三方 jar 文件沒法被掃描,所以不能被 Spring 容器管理。

8.2 解決方案

方式一:

在啓動類 SpringbootApplication 上添加 @Import(CacheConfirguration.class)。

方式二:

在 Maven 項目的 src/main/resources 目錄下建立 META-INF 文件夾,在該文件夾下再建立 spring.factories 文件,內容以下:

 

1

2

 

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

com.light.cache.CacheConfirguration

啓動項目,結果以下:

imageimage

9、條件配置

須要裝配的類:

 

1

2

3

4

5

6

7

8

9

10

11

 

public interface EncodingConvertor {

}

public class UTF8EncodingConvertor implements EncodingConvertor {

}

public class GBKEncodingConvertor implements EncodingConvertor {

}

配置類:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

 

@Configuration

public class EncodingConvertorConfiguration {

@Bean

public EncodingConvertor createUTF8EncodingConvertor() {

return new UTF8EncodingConvertor();

}

@Bean

public EncodingConvertor createGBKEncodingConvertor() {

return new GBKEncodingConvertor();

}

}

測試:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

 

@SpringBootApplication

public class SpringbootApplication extends SpringBootServletInitializer {

@Override

protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {

return application.sources(SpringbootApplication.class);

}

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootApplication.class, args);

Map<String, EncodingConvertor> map = context.getBeansOfType(EncodingConvertor.class);

System.out.println(map);

}

}

打印結果:

 

1

 

{createUTF8EncodingConvertor=com.light.springboot.config.UTF8EncodingConvertor@4c889f9d, createGBKEncodingConvertor=com.light.springboot.config.GBKEncodingConvertor@26f067d9}

從結果看出,Spring 幫咱們裝配了 2 個 Bean。

當咱們須要根據系統環境的字符集選擇性的裝配其中一個 Bean 時,須要結合 @Conditional 註解 和 Condition 接口使用。以下:

建立條件類:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

 

public class UTF8Condition implements Condition {

@Override

public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

String encoding = System.getProperty("file.encoding");

if (encoding != null) {

return "utf-8".equals(encoding.toLowerCase());

}

return false;

}

}

public class GBKCondition implements Condition {

@Override

public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

String encoding = System.getProperty("file.encoding");

if (encoding != null) {

return "gbk".equals(encoding.toLowerCase());

}

return false;

}

}

Condition 用於判斷是否進行裝配,須要實現 matches 方法。當方法返回 true 時表示須要裝配,不然反之。

修改配置類:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

 

@Configuration

public class EncodingConvertorConfiguration {

@Bean

@Conditional(UTF8Condition.class)

public EncodingConvertor createUTF8EncodingConvertor() {

return new UTF8EncodingConvertor();

}

@Bean

@Conditional(GBKCondition.class)

public EncodingConvertor createGBKEncodingConvertor() {

return new GBKEncodingConvertor();

}

}

在對應的 Bean 上添加 @Conditional 註解。

測試:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

 

@SpringBootApplication

public class SpringbootApplication extends SpringBootServletInitializer {

@Override

protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {

return application.sources(SpringbootApplication.class);

}

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootApplication.class, args);

System.out.println(System.getProperty("file.encoding"));

Map<String, EncodingConvertor> map = context.getBeansOfType(EncodingConvertor.class);

System.out.println(map);

}

}

打印結果:

 

1

2

 

UTF-8

{createUTF8EncodingConvertor=com.light.springboot.config.UTF8EncodingConvertor@24701bc1}

除了 @Conditional 以外,Spring Boot 還提供了其餘註解進行條件裝配:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

 

@ConditionalOnBean # 當指定 Bean 存在時進行裝配

@ConditionalOnMissingBean # 當指定 Bean 不存在時進行裝配

@ConditionalOnClass # 當指定 Class 在 classpath 中時進行裝配

@ConditionalOnMissingClass # 當指定 Class 不在 classpath 中時進行裝配

@ConditionalOnExpression # 根據 SpEL 表達式進行裝配

@ConditionalOnJava # 根據 JVM 版本進行裝配

@ConditionalOnJndi # 根據 JNDI 進行裝配

@ConditionalOnWebApplication # 當上下文是 WebApplication 時進行裝配

@ConditionalOnNotWebApplication # 當上下文不是 WebApplication 時進行裝配

@ConditionalOnProperty # 當指定的屬性名的值爲指定的值時進行裝配

@ConditionalOnResource # 當指定的資源在 classpath 中時進行裝配

@ConditionalOnCloudPlatform #

@ConditionalOnSingleCandidate #

10、打包運行

打包的形式有兩種:jar 和 war。

10.1 打包成可執行的 jar 包

默認狀況下,經過 maven 執行 package 命令後,會生成 jar 包,且該 jar 包會內置了 tomcat 容器,所以咱們能夠經過 java -jar 就能夠運行項目,以下圖:

imageimage

10.2 打包成部署的 war 包

讓 SpringbootApplication 類繼承 SpringBootServletInitializer 並重寫 configure 方法,以下:

 

1

2

3

4

5

6

7

8

9

10

11

12

 

@SpringBootApplication

public class SpringbootApplication extends SpringBootServletInitializer {

@Override

protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {

return application.sources(SpringbootApplication.class);

}

public static void main(String[] args) {

SpringApplication.run(SpringbootApplication.class, args);

}

}

修改 pom.xml 文件,將 jar 改爲 war,以下:

 

1

 

<packaging>war</packaging>

打包成功後,將 war 包部署到 tomcat 容器中運行便可。

11、參考資料

相關文章
相關標籤/搜索