SpringBoot - 淺析自動裝配過程及相關注解

前言

在Spring階段,我們被各種XML文件配置或者配置類所困擾着,Spring有着“配置地獄”之稱

爲了簡化新 Spring 應用的初始搭建以及開發過程,提出了自動裝配的SpringBoot,
該框架遵循“約定優於配置”,使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置


約定優於配置

約定優於配置:按照約定的規範編程,而不是按照配置

以Spring+Mybatis爲例:

需要3個文件:Spring基本配置文件(設置自動掃描等)、mybatis配置文件(可以省略)、Spring+mybatis配置文件(bean裝配mybatis配置)
在這裏插入圖片描述

mybatis連接數據庫的配置必不可少:

    <!--DataSource:使用Spring的數據源替換Mybatis的配置
        使用spring提供的jdbc
    -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <!--sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />

        <!--綁定Mybatis配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--綁定Mapper文件-->
        <property name="mapperLocations" value="classpath:com/learn/dao/UserMapper.xml"/>
    </bean>

    <!--SqlSessionTemplate就是我們使用的sqlSession-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!--只能構造器注入,沒有setter方法-->
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>

而在SpringBoot+Mybatis:

一個application.yml配置文件即可
在這裏插入圖片描述

只需稍微配置:

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.jdbc.Driver


mybatis:
  type-aliases-package: com.learn.pojo
  mapper-locations: classpath:mybatis/mapper/*.xml

爲什麼這麼簡單就配置好了?

因爲在SpringBoot中設置了默認約定,SpringBoot會自動裝配好我們需要的東西
如果需要自定義一些配置,在yml文件中配置,即開發人員僅需規定應用中不符合約定的部分,在沒有規定配置的地方,採用默認配置

SpringBoot中有哪些約定呢?

  • Maven的目錄結構:src-main-resources,src-main-java,resources文件夾,存放資源配置文件,java文件夾存放java程序,必須要SpringbootApplication.java同層才能運行。默認的編譯生成的類都在targe文件夾下面
  • springboot默認的配置文件必須是application.命名的yml文件或者properties文件(可以通過加上-後綴設置不同文件:application-dev.yml)
  • application.yml中設置屬性需要按層次格式,Spring->datasource->url;mybatis->type-aliases-package等

@SpringBootApplication

SpringBoot有一個啓動類SpringbootApplication

package com.springbootweb;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Springbootweb01Application {

    public static void main(String[] args) {
        SpringApplication.run(Springbootweb01Application.class, args);
    }
}

這是SpringBoot的入口,SpringBoot的啓動就是從該main方法啓動

它主要加載了@SpringBootApplication註解主配置類

來分析@SpringBootApplication註解

在這裏插入圖片描述

上面四個是元註解,下面的3個是我們需要關注的註解

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM,
    classes = TypeExcludeFilter.class), @Filter(type =
    FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })

@SpringBootConfiguration較簡單:
在這裏插入圖片描述

在Spring中就學了,@Configuration註解表示該類爲Spring的配置類
這個@SpringBootConfiguration註解功能一樣的


@EnableAutoConfiguration

EnableAutoConfiguration,直白的名字:開啓自動配置
分析:

在這裏插入圖片描述

該註解上有兩個重要的註解:

  • @AutoConfigurationPackage:添加該註解的類所在的package作爲自動配置package進行管理

  • @Import(AutoConfigurationImportSelector.class):導入了一個
    AutoConfigurationImportSelector選擇器給Spring容器中來導入一些組件

@AutoConfigurationPackage註解:導入AutoConfigurationPackages.Registrar註冊器
在這裏插入圖片描述

在這裏插入圖片描述

{ @link ImportBeanDefinitionRegistrar } to store the base package from the importing configuration.

就不深入解析了,該註解大致的意思就是:當SpringBoot應用啓動時默認會將啓動類所在的package作爲自動配置的package,所以說我們的包應當和SpringBootApplication類同層

在這裏插入圖片描述

@Import(AutoConfigurationImportSelector.class)

版本爲2.2.6 RELEASE,不同的版本有一定的更改

父類裏面規定了一個方法叫selectImports方法,查看了selectImports這個方法裏面的代碼內容就能知道導入了哪些組件:
在這裏插入圖片描述

調用了getAutoConfigurationEntry方法,顧名思義:獲得自動裝配組件

在這裏插入圖片描述

該方法會返回configurations,這個就是配置對象集合

通過getCandidateConfigurations方法獲得,獲得候選配置

在這裏插入圖片描述

SpringFactoriesLoader.loadFactoryNames是這裏關鍵的方法,Spring工廠加載類

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

該方法會掃描具有META-INF/spring.factories文件的jar包,把這個文件的urls拿到之後並把這些urls遍歷,最終把這些文件整成一個properties對象

然後它從properties對象裏邊獲取一些值,把這些獲取到的值來加載我們最終要返回的這個結果result,result就是我們要交給Spring容器中的所有組件

factoryTypeName就是我們傳過來的Class的這個類名。

是前面SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()),傳入的getSpringFactoriesLoaderFactoryClass()方法中得到,從properties中獲取到EnableAutoConfiguration.class類名:
在這裏插入圖片描述
SpringFactoriesLoader會根據這個EnableAutoConfiguration.class去spring.factories找EnableAutoConfiguration.class所對應的values,並返回

在這裏插入圖片描述


spring.factories

META-INF/spring.factories文件在Spring-boot-autuoconfigure包下
在這裏插入圖片描述

這個配置文件配置了很多自動裝配的信息:
在這裏插入圖片描述

這些自動裝配類xxxAutoConfiguration都是SpringBoot自動裝配的相關類,是SpringBoot自動裝配的核心

每個xxxAutoConfiguation類都定義了相關bean的實例化配置,說明了哪些bean可以被自動配置,什麼條件下可以自動配置,並把這些bean實例化出來

我們打開一個常見的DataSourceAutoConfiguration,進入查看

在這裏插入圖片描述

  • @Configuration(proxyBeanMethods = false):表明這是一個配置類,proxyBeanMethods = false表示該類不會被代理,提供性能
  • @ConditionalOnClass:當SpringIoC容器內存在指定Class的條件,表示對應的jar包是否導入了,這類註解用來判斷是否執行自動裝配
  • @EnableConfigurationProperties(DataSourceProperties.class):導入對應的啓動裝配屬性類:DataSourceProperties
  • @Import({ DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class }):相關的配置類

主要就是DataSourceProperties,這個類中定義自動裝配的配置:

在這裏插入圖片描述
表示配置前綴是:spring.datasource

內部屬性有:
在這裏插入圖片描述

這些就是在application.yml文件中自定義配置的屬性:

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

到這,應該明白了 spring.factories的作用:

  • 在該文件中配置好SpringBoot需要的自動配置類,當啓動SpringBoot時會加載該文件,並一個個加載這些xxxAutoConfiguration類
  • 而在這些類中,會有一類ConditionalOnXxx註解判斷該類是否自動裝配
  • 如果是自動裝配,會加載EnableConfigurationProperties註解導入的Properties類,該類中會有成員變量,這些變量對應着yml文件可以設置的字段

總結

我們可以大致總結自動配置:

  • SpringBootApplication啓動類,是SpringBoot程序的入口,關鍵在與@SpringBootApplication註解

  • 該註解有兩個重要的元註解:@SpringBootConfiguration表示該類爲Spring的配置類;@EnableAutoConfiguration

  • @EnableAutoConfiguration有兩個重要元註解:
    @AutoConfigurationPackage表示當SpringBoot應用啓動時默認會將啓動類所在的package作爲自動配置的package
    @Import(AutoConfigurationImportSelector.class)導入了一個選擇器

  • AutoConfigurationImportSelector的selectImports方法決定SpringBoot導入的組件,經過一系列的方法調用最終會使用SpringFactoriesLoader加載器負責加載配置類名,loadSpringFactories方法讀取自動配置工程的META-INF/spring.factories配置文件,加載配置類的全類名,包裝成Properties對象,返回result就是交給Spring容器的組件

  • spring.factories內部編寫好了全部的自動裝配類,啓動SpringBoot時,會加載這些自動裝配類xxxAutoConfiguration,這些自動裝配類有元註解ConditionalOnXxx判斷是否自動裝配,如果判斷確定自動裝配,會加載相關的Properties屬性類,該屬性類屬性字段對應yml文件中的字段

學海無涯苦作舟

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章