1. 程式人生 > >Spring Boot 入門(三): 自動化配置實現

Spring Boot 入門(三): 自動化配置實現

自動化配置實現

我們在上章編寫入門案例的時候,我們使用的是Spring Mvc 作為我們的表現層框架,但是我們都知道我們要使用Spring Mvc 我們就需要在web.xml檔案中配置Spring Mvc 的前端控制器DispatcherServlet。但是我們在編寫入門案例的時候,我們並沒有去做任何的配置,那麼我們為什麼可以使用呢?原因是Spring Boot 給我們做了自動化配置,下面我們學習一下Spring Boot 中自動化配置的原理。

  • 入口類和@SpringBootApplication — Spring Boot 專案一般都會有*Application的入口類, 入口類中會有main方法,這是一個標準的Java應用程式的入口方法。Spring Boot 會自動掃描@SpringBootApplication
    所在類的同級包及其下級包中的Bean(如果是jpa專案還會自動掃描標註@Entity的實體類)@SpringBootApplication註解是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 {};
}

通過原始碼我們發現在@SpringBootApplication這個註解上又定義了一些其他的註解,如:@SpringBootConfiguration@EnableAutoConfiguration,我們把這樣的註解稱為組合註解,組合註解的作用就是簡化我們的註解使用,我們在某一個類上使用了@SpringBootApplication那麼就相當於在該類上使用了該註解上定義的其他的三個註解。

  • @SpringBootConfiguration註解 — 看到Configuration註解,就想到它的作用就是用來替換配置檔案的。而@SpringBootConfiguration註解是做什麼的?我們看下它的原始碼。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.springframework.boot;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}

通過原始碼,我們發現@SpringBootConfiguration註解也是組合註解,它的另一個註解就是 @Configuration ,SpringBoot 推薦我們使用該註解來替換配置檔案。

  • @EnableAutoConfiguration 支援自動化配置註解

  • DispatcherServlet 自動化配置分析 — DispatcherServlet 自動化配置原始碼解析 — 入門案例中我們只是加入了spring-boot-starter-web這個依賴,就可以實現DispatcherServlet相關配置。這是為什麼?注意當我們加入了spring-boot-starter-web的依賴以後,根據maven的依賴傳遞特性,會自動將一些包加入到我們的專案中。比如會自動新增tomcat 和springmvc的依賴。 在這裡插入圖片描述

    那麼這些依賴包的確加入到我們的專案中,那麼怎麼完成自動配置?因為加入spring-boot-starter-web依賴的時候,會自動將另外的一個依賴加入進來,這個依賴包就是spring-boot-autoconfigure:2.0.6.RELEASE這個包定義了很多技術點的自動配置在這裡插入圖片描述 在這裡插入圖片描述 找到這個jar後,讓我們揭開DispatcherServlet自動化註解的神祕面紗。首先找到org.springframework.boot.autoconfigure.web.servlet包下的DispatcherServletAutoConfiguration類。由於原始碼太多,這裡不貼全部原始碼。看下原始碼資訊:

@AutoConfigureOrder(Ordered.*HIGHEST_PRECEDENCE*)
@Configuration
@ConditionalOnWebApplication(type = Type.*SERVLET*)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
@EnableConfigurationProperties(ServerProperties.class)
public class DispatcherServletAutoConfiguration {
	/*
	 * The bean name for a DispatcherServlet that will be mapped to the root URL "/"
	 */
	public static final String *DEFAULT_DISPATCHER_SERVLET_BEAN_NAME*= "dispatcherServlet";

我們通過原始碼可以看到DispatcherServletAutoConfiguration類上面有6個註解,包括我們最熟悉的@Configuration註解,下面我們一一分析下註解的含義: — @AutoConfigureOrder註解:指定自動註解順序。取值為int的最小值,優先順序最高。 — @Configuration註解:這個大家都不陌生了,是指定該類為配置類。類似我們定義的applicationContext.xml檔案。 — @ConditionalOnWebApplication:這是一個新註解,為條件註解,表示當前專案是一個web環境的條件下。 — @ConditionalOnClass:判斷當前路徑下有指定的類的條件下。 — @ AutoConfigureAfter:定義該配置類的載入順序;該類表示後於ServletWebServerFactoryAutoConfiguration.class載入。

— 其實實現自動化配置主要是依據條件註解來完成的,有了條件註解了以後,就會根據這些條件,來判斷是否啟用這些配置。

  • 以下是些條件註解的總結: @ConditionaOnBean -> 當容器中存在指定Bean的條件下 @ConditionaOnClass -> 當類路徑下存在指定類的條件下 @ConditionaOnMissingBean -> 當容器中不存在指定Bean的條件下 @ConditionaOnMissingClass -> 當類路徑下不存在指定類的條件下 @ConditionaOnProperty -> 指定的屬性是否存在指定的值 @ConditionaOnResource -> 類路徑下是否存在指定的值 @ConditionaOnWebApplication -> 是web環境的條件下 @ConditionaOnNotWebApplication -> 不是web環境的條件下 以上是些常用的條件註解,先總結到這裡。 入門專案傳送門:Springboot 入門(一):入門案例 - July_whj - CSDN部落格

#springboot/02自動化配置實現