Spring Boot 入門(配置、原理、日誌)

之前只在項目中使用,這裏還是再總結一下:


SpringBoot 系列:
1. Spring Boot 入門、原理、日誌
2. Spring Boot中的Thymeleaf、自動配置、國際化、容器
3. SpringBoot 數據訪問、啓動配置原理以及自定義Starter
4. SpringBoot 與緩存並整合 Redis
5. SpringBoot 與消息隊列並整合 RabbitMQ


Spring Boot 入門

概述

Spring Boot 簡化了 Spring 應用開發:

  • 由原來的 Spring 全家桶簡化成 SpringBoot 的 J2EE一站式解決方案
  • 以及後來的 Spring Cloud 分佈式整體解決方案。

優點:

  • 快速創建獨立運行的 Spring 項目並可以集成主流框架
  • 使用嵌入式的 Servlet 容器,應用無需打成 WAR 包
  • starters 自動依賴與版本控制
  • 自動化配置,簡化開發
  • 無需配置 XML,無代碼生成

單體應用與微服務:
單體應用,即所有的功能模塊都在一個應用中,使用複製形式實現水平擴展。
而微服務其實是一種架構風格,一個應用由一組小型服務組成,通過HTTP的方式進行互通;
每一個功能元素最終都是一個可獨立替換和獨立升級的軟件單元。


環境配置

1.在 pom.xml 中配置:

		<!-- 指定父項目,由父項目管理Spring Boot 應用裏面的所有依賴版本 -->
		<parent>
	        <groupId>org.springframework.boot</groupId>
	        <artifactId>spring-boot-starter-parent</artifactId>
	        <version>1.5.9.RELEASE</version>
	    </parent>
	    <dependencies>
	    	<!-- 通過 starter 場景啓動器(其它 acvitmq 等),導入 web 模塊 -->
	        <dependency>
	            <groupId>org.springframework.boot</groupId>
	            <artifactId>spring-boot-starter-web</artifactId>
	        </dependency>
	    </dependencies>

2.編寫啓動 Spring Boot 主程序:

		/**
		 *  @SpringBootApplication 來標註一個主程序類,說明這是一個Spring Boot應用
		 */
		@SpringBootApplication
		public class SpringBootDemoApplication{
		    public static void main(String[] args) {
		        SpringApplication.run(SpringBootDemoApplication.class,args);//啓動應用
		    }
		}

此時就配置完成可以編寫 Controller 了:

		@Controller
		public class HelloController {
		
		    @ResponseBody
		    @RequestMapping("/hello")
		    public String hello(){
		        return "Hello World!";
		    }
		}

只需要運行 Main 方法就可以啓動應用,打包也只需打成 JAR 可執行包,配置打包插件:

		<build>
	        <plugins>
	            <plugin>
	                <groupId>org.springframework.boot</groupId>
	                <artifactId>spring-boot-maven-plugin</artifactId>
	            </plugin>
	        </plugins>
	    </build>

3.其實也可以使用 Spring Initializr 來快速創建
在這裏插入圖片描述


SpringBootApplication 註解

由前面可知 SpringBootApplication 註解用於標註一個主程序類,說明這是一個Spring Boot應用,而它其實是一個組合註解:
1
1.@SpringBootConfiguration:標註在某個類上,表示這是一個Spring Boot的配置類;

  • @Configuration:使用的是 Spring 的註解來標註配置類,配置類其實是配置文件,使用的是 @Component 被標註成 Spring 的組件。

2.@EnableAutoConfiguration:開啓自動配置功能;以前我們需要配置的東西,Spring Boot幫我們自動配置,也是一個組合註解,如下:
在這裏插入圖片描述

  • @AutoConfigurationPackage:自動配置包,使用 Spring 的底層註解@Import(AutoConfigurationPackages.Registrar.class) ,會將主配置類所在包及下面所有子包裏面的組件掃描到 Spring 容器。
  • @Import(EnableAutoConfigurationImportSelector.class):將我們所需要的場景組件的自動配置類(xxxAutoConfiguration)導入到容器。從類路徑下的META-INF/spring.factories中獲取EnableAutoConfiguration指定的值,將這些值作爲自動配置類導入到容器中,幫助我們自動配置。

配置文件

Spring Boot 全局配置文件可以對自動配置的默認配置值進行修改,而配置文件有兩種形式:

  • application.properties:我們正常使用的配置文件
		server.port = 8081
  • application.yml:使用 YAML 標記語言的文件,以數據爲中心,比json、xml更適合作配置文件
		server:
			port: 8081
		  	context-path: /

YAML 語法

基本語法

  • k:(空格)v 表示一堆鍵值對(空格不能省略)
  • 以空格縮進的形式來控制層級關係,即左對齊的一列是同一層級
  • 屬性和值是大小寫敏感的

值的類型

  1. 字面量(數字,字符串,布爾):直接寫,字符串默認不用加上引號;加上雙引號則不會轉義特殊字符,而單引號會轉移特殊字符。
  2. 對象、Map:在下一行寫對象的屬性和值的關係
		# 第一種
		user:
			name: moke
			age: 22
		# 第二種
		user: {name: moke,age: 22}
  1. 數組、List、Set
		# 第一種
		myList:
			- a
			- b
		# 第二種
		myList: [a,b]

值的注入
比如上面我們配置了一個 user 對象的值,那麼如何注入到我們容器的對象中呢,如下:

  1. 配置文件處理器
		<!--導入配置文件處理器-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</dependency>
  1. yml 配置值
		user:
		    name: hello
		    age: 18
		    boss: false
		    birth: 2017/12/12
		    father:
		      name: moke
		      age: 30
  1. 注入值:@ConfigurationProperties 和 @Value
		//使用 @ConfigurationProperties
		@Component
		@ConfigurationProperties(prefix = "user")
		public class User{...}
		//使用 @Value
		public class User{
			@Value("${user.name}")
			private String name;
			...
		}

區別:
在這裏插入圖片描述@PropertySource、@ImportResource、@Bean 註解:
@PropertySource:加載指定的配置文件

		@PropertySource(value = {"classpath: redis.yml"})

@ImportResource:導入 Spring 的配置文件,即使用我們原來在 Spring 中使用 xml 配置文件

		@ImportResource(locations = {"classpath: beans.xml"})

但是 SpringBoot 不建議使用 xml 配置文件,而是使用配置類:

		@Configuration
		public class MyConfig{
			//將方法的返回值添加到容器中,默認的 id 就是方法名
			@Bean
			public User user(){
				return new User();
			}
		}

配置佔位符

		person:
			name: 張三${random.uuid}
			age: ${random.int}

Profile 多環境

  1. 多 Profile 文件
    比如在主配置文件編寫的時候,文件名:application.yml、application-test.yml、application-dev.yml,可以在住配置文件中激活環境所需要的配置文件:
		spring:
		  profiles:
		    active: test
  1. 多文檔塊
    不需要編寫多個配置文件,使用 — 來劃分不同的文檔塊,不同文檔塊指定不同的環境
		spring:
		  profiles:
		    active: dev
		---
		spring:
		  profiles: test
		server:
		  port: 8081
		---
		spring:
		  profiles: dev
		server:
		  port: 8081
  1. 激活指定 profile
    之前我們激活指定 profile 都是通過在配置文件中配置 spring.profiles.active 來激活,也可以使用命令行的方式激活,在啓動時添加參數:–spring.profiles.active=dev;或者使用虛擬機參數:Dspring.profiles.active=test。

加載配置文件

配置文件加載位置,優先級從高到低,配置會互補,而相同則覆蓋低優先級配置內容

  1. file:./config/
  2. file:./
  3. classpath:/config/
  4. classpath:/

或者通過 spring.config.location 來改變默認的配置文件位置(配置文件/命令行)

加載外部配置(由高到低)
1.命令行參數:所有的配置都可以在命令行上進行指定
2.來自java:comp/env的JNDI屬性
3.Java系統屬性(System.getProperties())
4.操作系統環境變量
5.RandomValuePropertySource配置的random.*屬性值
6.jar包外部的application-{profile}.properties或application.yml(帶spring.profile)配置文件
7.jar包內部的application-{profile}.properties或application.yml(帶spring.profile)配置文件
8.jar包外部的application.properties或application.yml(不帶spring.profile)配置文件
9.jar包內部的application.properties或application.yml(不帶spring.profile)配置文件

10.@Configuration註解類上的@PropertySource
11.通過SpringApplication.setDefaultProperties指定的默認屬性


自動配置原理

配置文件可以配置的屬性:官方文檔

之前有說 SpringBoot 啓動的時候使用 @EnableAutoConfiguration 開啓了自動配置功能,而 @EnableAutoConfiguration 是利用 EnableAutoConfigurationImportSelectort 向容器導入組件,相關的方法:
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述
把從 spring.factories 中掃描到的文件內容封裝成 properties 對象,然後就可以從 properties 中獲取到 EnableAutoConfiguration.class 類中對應的值,然後把它們添加到容器中。

我們以 AciveMQautoConfiguration 爲例,這是 ActiveMQ 的自動配置類
在這裏插入圖片描述
而 Properties 類默認是通過 spring.factories 中的 url 獲取到的 Properties,而通過 @ConfigurationProperties 註解允許從我們自定義的配置文件中注入修改的值:
在這裏插入圖片描述


@Conditional 註解

在自動配置加載 Properties 類前,會先進行條件的判斷,自動配置類必須在一定的條件下才能生效;
而它們都是基於 Spring 的底層註解 @Conditional,如下:
在這裏插入圖片描述
在這裏插入圖片描述
這些由 @Conditional 派生出來的不同的條件註解,常見的如下:

@Conditional擴展註解 作用(判斷是否滿足當前指定條件)
@ConditionalOnJava 系統的java版本是否符合要求
@ConditionalOnBean 容器中存在指定Bean;
@ConditionalOnMissingBean 容器中不存在指定Bean;
@ConditionalOnExpression 滿足SpEL表達式指定
@ConditionalOnClass 系統中有指定的類
@ConditionalOnMissingClass 系統中沒有指定的類
@ConditionalOnSingleCandidate 容器中只有一個指定的Bean,或者這個Bean是首選Bean
@ConditionalOnProperty 系統中指定的屬性是否有指定的值
@ConditionalOnResource 類路徑下是否存在指定資源文件
@ConditionalOnWebApplication 當前是web環境
@ConditionalOnNotWebApplication 當前不是web環境
@ConditionalOnJndi JNDI存在指定項

那我們如何知道那些自動配置類生效了呢?
配置 debug=true,會在啓動時打印自動配置報告:
在這裏插入圖片描述


日誌框架

在這裏插入圖片描述
Spring 框架默認使用的是 JCL,而 SpringBoot 改爲 SLF4J 和 logback。


SLF4J 的原理

我們只需要調用日誌門面 SLF4J 抽象層中的方法,而不是直接調用日誌的實現類,除了導入 SLF4J 還需要導入相應日誌的實現(可以不是默認的 logback,但是需要一箇中間層來適配),參考官方的圖片:
在這裏插入圖片描述
此外,在開發過程中,框架會使用自己的底層配置的日誌實現框架,那如何都通過 SLF4J 提供的方法進行統一的日誌輸出呢?將應用中其他 日誌實現 替換成調用 SLF4J 的中間包,參考官方圖片:
在這裏插入圖片描述
而這些中間包的引入,可以通過SpringBoot 的依賴關係,看到 SpringBoot 都幫我們完成了:
在這裏插入圖片描述
所以在引入其他框架時,我們只需要把這個框架本身的日誌框架排除,比如 SpringBoot 對 Spring 框架中 commons-logging 的排除:
在這裏插入圖片描述

SpringBoot 中使用 SLF4J

在 SpringBoot 中使用 SLF4J

		Logger logger = LoggerFactory.getLogger(getClass());

		//日誌的級別;
		//由低到高   trace<debug<info<warn<error
		//可以調整輸出的日誌級別;日誌就只會在這個級別以以後的高級別生效
		logger.trace("這是trace日誌...");
		logger.debug("這是debug日誌...");
		//SpringBoot默認給我們使用的是info級別的,沒有指定級別的就用SpringBoot默認規定的級別;root級別
		logger.info("這是info日誌...");
		logger.warn("這是warn日誌...");
		logger.error("這是error日誌...");

而我們可以在配置文件中配置級別,以及使用日誌的其他功能:

		logging:
		  # 日誌打印級別
		  level: trace
		  # 可以指定完整的路徑,以及生成的日誌文件名
		  file: F:/springboot.log
		  # 在當前磁盤的根路徑下創建spring文件夾和裏面的log文件夾;使用 spring.log 作爲默認文件
		  path: /spring/log
		  pattern:
		    # 在控制檯輸出的日誌的格式
		    console: '%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n'
		    # 指定文件中日誌輸出的格式
		    file: '%d{yyyy-MM-dd} === [%thread] === %-5level === %logger{50} ==== %msg%n'
		#	 日誌的格式
		#    %d表示日期時間,
		#    %thread表示線程名,
		#    %-5level:級別從左顯示5個字符寬度
		#    %logger{50} 表示logger名字最長50個字符,否則按照句點分割。
		#    %msg:日誌消息,
		#    %n是換行符

還可以自己定義配置文件
給類路徑下放上每個日誌框架自己的配置文件即可;SpringBoot就不會使用他默認配置的

Logging System Customization
Logback logback-spring.xml, logback-spring.groovy, logback.xml or logback.groovy
Log4j2 log4j2-spring.xml or log4j2.xml
JDK (Java Util Logging) logging.properties

帶 spring 和不帶 spring 是有區別的,比如:

  • logback.xml:直接就被日誌框架識別了;
  • logback-spring.xml:日誌框架就不直接加載日誌的配置項,由SpringBoot解析日誌配置,可以使用SpringBoot的高級Profile功能

SpringBoot Profile: 可以指定某段配置只在某個環境下生效

		<springProfile name="dev">
		    <!-- dev環境下的輸出格式 -->
		  	<pattern>%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n</pattern>
		</springProfile>

切換日誌框架
可以按照slf4j的日誌適配圖,進行相關的切換,比如切換到 slf4j+log4j2,先排除再引入:

   		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>spring-boot-starter-logging</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>
		<dependency>
		  <groupId>org.springframework.boot</groupId>
		  <artifactId>spring-boot-starter-log4j2</artifactId>
		</dependency>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章