spring boot知識總結
目錄
關於@SpringBootApplication這個註解的作用,記住下面這張圖即可:
自動配置幕後英雄:SpringFactoriesLoader詳解
Spring Boot是什麼?
Spring Boot是為簡化Spring MVC/spring的開發而生的專案。主要從以下三個方面:
-
simplify configuration 簡化配置
-
simplify deployment簡化部署
-
simplify monitor 簡化系統監控
spring boot由四個主要的元件組成:
-
Spring Boot Starter:
-
Automatically Configuration.
-
CLI. Use with groovy.
-
Actuator
Spring Boot Starter
spring boot starter起到的作用是,把一些列的依賴結合起來,依賴之間可以像java類繼承一樣引用對方。這樣的好處是解決了依賴之間衝突的問題(這個問題在maven使用過程中非常常見),減少了依賴的數量。
下面是一個spring boot starter web的例子:
在這個時代,使用spring開發的應用大多數都是在使用springMVC開發web應用,為了幫我們快速搭建並開發一個web專案,spring boot為我們提供了spring-boot-starter-web自動配置模組。
只要將spring-boot-starter-web加入專案的maven依賴,我們就得到了一個直接可執行的web應用,在當前專案下執行spring boot:run,就可以直接啟動一個使用了嵌入式Tomcat服務的web應用,只不過我們還沒有提供任何可以響應web請求的controller,所以當前訪問任何的路徑都會返回一個spring boot預設提供的錯誤頁面(white label error page). 如果在當前專案下新建一個服務根路徑web請求的controller:
@RestController
public class IndexController {
@RequestMapping("/")
public String index(){
return "hello, there";
}
}
重新執行mvn spring-boot:run並訪問http://localhost:8080,錯誤頁面將被controller返回的訊息所替代。至此,一個簡單的web應用就已經這樣完成了。但是,毫無疑問背後的潛規則(約定)是我們必須去了解的。
約定1:專案結構層面的約定
與傳統打包為war包的java web應用的差異在於,靜態檔案和頁面模板的存放位置變了,原來是放在src/main/webapp目錄下的一系列資源,現在都統一放在了src/main/resources下。
約定2:springMVC框架層面的約定和定製
spring-boot-starter-web預設為我們配置了一些springMVC必要元件
- ViewResolver
- Converter,Formatter等bean註冊到IoC
- HttpMessageConverter
- MessageCodesResolver
當然,我們完全可以自己配置這些東西,而不用它提供的配置。
約定3:嵌入式web容器層面的約定和定製
- 預設使用嵌入式tomcat作為web容器對外提供http服務,預設使用8080埠對外監聽和提供服務
- 假設不行使用簽署tomcat,可引入spring-boot-starter-jetty或spring-boot-starter-undertow作為替代
- 假設不想使用8080作為預設埠,可以更改配置項server.port使用自己指定的埠號,如:server.port = 9000
Automatically Configuration
自動配置的主要職責是:減少spring的配置。
自動配置是什麼,用一個例子比較好說明。當我們把spring-boot-starter-web加入到專案的maven依賴裡以後,它就會自動的新增spring mvc的相關依賴,如果spring mvc相關的配置在classpath裡面被scan到,它就會自動的將相關的bean加到IoC容器裡面(messageConvert等)。spring啟動的時候會掃描classpath並且去找META-INF/spring.factories這個檔案,然後去載入configuration. 這個檔案的格式是 key = value的格式,並且key和value都必須是java 類的全限定名(Fully qualified), 比如:
exmaple.MyService = example.MyServiceImpl
如果我們使用了註解@EnableAutoConfiguration,它會去載入,例項化所有加了@Configuration的註解的類到IoC容器裡去(ApplicationContext),通常,這個註解會用在主類裡邊,並且主類一般是在開發包的最頂部,因此它就可以掃描到所有的類。
@EnableAutoConfiguration這個註解的示意圖如下:
@ComponentScan:
會自動掃描包路徑下面的所有@Controller、@Service、@Repository、@Component 的類。
basePackages指定掃描的包,includeFilters包含那些過濾,excludeFilters不包含那些過濾,useDefaultFilters預設的過濾規則是開啟的,如果我們要自定義的話是要關閉的
@Configuration
把一個類標記為IoC容器的一個bean
關於@SpringBootApplication這個註解
這個註解由下面幾個註解組成:
@Configuration
它就是JavaConfig形式的Spring Ioc容器的配置類使用的那個@Configuration.
這裡的啟動類標註了@Configuration之後,本身其實也是一個IoC容器的配置類。
任何一個標註了@Configuration的Java類定義都是一個JavaConfig配置類。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
這個springBoot啟動類等價於下面的寫法:
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class AppConfiguration{
@Bean
public Controller controller(){
return new Controller();
}
}
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(AppConfiguration.class, args);
}
}
經過這樣的改造之後,就很明白了,啟動類就是一個普通的main函式啟動類,沒有什麼特別之處,在main 裡面呼叫了一個方法而已。
而由@Configuration修飾的AppConfiguration類定義就是一個普通的javaConfig形式的IoC容器配置類而已。
@ComponentScan
@ComponentScan這個註解在Spring中很重要,它對應XML配置中的元素,@ComponentScan的功能其實就是自動掃描並載入符合條件的元件(比如@Component和@Repository等)或者bean定義,最終將這些bean定義載入到IoC容器中。
我們可以通過basePackages等屬性來細粒度的定製@ComponentScan自動掃描的範圍,如果不指定,則預設Spring框架實現會從宣告@ComponentScan所在類的package進行掃描。
p.s. 所以SpringBoot的啟動類最好是放在root package下,因為預設不指定basePackages
@EnableAutoConfiguration
@EnableAutoConfiguration是藉助@Import的幫助,將所有符合自動配置條件的bean定義載入到IoC容器,僅此而已。
它本事也是一個複合的註解,它的實現如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
...
}
最關鍵的要屬@Import(EnableAutoConfigurationImportSelector.class),藉助EnableAutoConfigurationImportSelector,@EnableAutoConfiguration可以幫助SpringBoot應用將所有符合條件的@Configuration配置都載入到當前SpringBoot建立並使用的IoC容器.
藉助於Spring框架原有的一個工具類:SpringFactoriesLoader的支援,@EnableAutoConfiguration可以智慧的自動配置功效才得以大功告成.
自動配置幕後英雄:SpringFactoriesLoader詳解
SpringFactoriesLoader屬於Spring框架私有的一種擴充套件方案,其主要功能就是從指定的配置檔案META-INF/spring.factories載入配置。
配合@EnableAutoConfiguration使用的話,它更多是提供一種配置查詢的功能支援,即根據@EnableAutoConfiguration的完整類名org.springframework.boot.autoconfigure.EnableAutoConfiguration作為查詢的Key,獲取對應的一組@Configuration類.
以下是從springBoot的:spring-boot-autoconfigure依賴包中的截圖:
@EnableAutoConfiguration自動配置的魔法就是:從classpath中搜尋所有的META-INF/spring.factories配置檔案,並將其中org.springframework.boot.autoconfigure.EnableautoConfiguration對應的配置項通過反射(Java Refletion)例項化為對應的標註了@Configuration的JavaConfig形式的IoC容器配置類,然後彙總為一個並載入到IoC容器。
在我們啟動spring boot的app時會呼叫一個SpringBootApplication的run方法。這個方法在執行過程中會去主動初始化需要用到的bean。其重要實現如下:
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
if (result != null) {
return result;
} else {
try {
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
LinkedMultiValueMap result = new LinkedMultiValueMap();
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 = properties.entrySet().iterator();
while(var6.hasNext()) {
Entry<?, ?> entry = (Entry)var6.next();
List<String> factoryClassNames = Arrays.asList(StringUtils.commaDelimitedListToStringArray((String)entry.getValue()));
result.addAll((String)entry.getKey(), factoryClassNames);
}
}
cache.put(classLoader, result);
return result;
} catch (IOException var9) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var9);
}
}
}
可以看到,是從一個名字(變數FACTORIES_RESOURCE_LOCATION)叫spring.factories的資原始檔中,讀取所有的配置資訊存放在了一個LinkedMultiValueMap型別的區域性變數result當中。
Acutator
spring提供了actutator用於幫助我們監控服務的各種狀態:
路徑 | 作用 |
info |
know the service situation |
error | |
autoconfig | list config decisions |
beans | List all the config beans |
dump | List application’s thread information |
/env/{name} | list all the environment variables |
health | |
info | |
/metrics/{name} | list the realated index |
shutdown | shut down the service |
trace | list the recent quest metadata,include request and response header |
configprops | list all the @ConfigurationProperties |
spring boot啟動過程
spring boot專案的啟動過程大致如下圖: