02 SpringBoot配置方式

在入門案例中,我們沒有任何的配置,就可以實現一個SpringMVC的項目了,快速、高效!
但是有同學會有疑問,如果沒有任何的xml,那麼我們如果要配置一個Bean該怎麼辦?比如我們要配置一個數據庫連
接池,以前會這麼配置:
現在該怎麼做呢? 

1、Spring配置歷史

事實上,在Spring3.0開始,Spring官方就已經開始推薦使用java配置來代替傳統的xml配置了,我們不妨來回顧一下

Spring的歷史:

Spring1.0時代,在此時因爲jdk1.5剛剛出來,註解開發並未盛行,因此一切Spring配置都是xml格式,想象一下所有的bean都用xml配置,細思極恐啊,心疼那個時候的程序員2秒

Spring2.0時代,Spring引入了註解開發,但是因爲並不完善,因此並未完全替代xml,此時的程序員往往是把xml與註解進行結合,貌似我們之前都是這種方式。

Spring3.0及以後,3.0以後Spring的註解已經非常完善了,因此Spring推薦大家使用完全的java配置來代替以前的xml,不過似乎在國內並未推廣盛行。然後當Spring Boot來臨,人們才慢慢認識到java配置的優雅。

2、嘗試java配置

2.1、配置類方式

以前配置數據源是通過xml文件實現的,例如:

 

現在通過定義配置類:

數據庫配置:

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://47.100.229.xxx:3306/springStudy?useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=xxxx
jdbc.initialSize=1
jdbc.minIdle=3
jdbc.maxActive=20
jdbc.maxWait=60000

配置類代碼:

package rui.config;

import com.alibaba.druid.pool.DruidDataSource;
import jdk.nashorn.internal.objects.annotations.Property;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import javax.sql.DataSource;

/*數據庫配置類*/
@Configuration
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {
    @Value("${jdbc.driverClassName}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;
    @Value("${jdbc.initialSize}")
    private int initialSize;
    @Value("${jdbc.minIdle}")
    private int minIdle;
    @Value("${jdbc.maxActive}")
    private int maxActive;
    @Value("${jdbc.maxWait}")
    private int maxWait;

    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setInitialSize(initialSize);
        dataSource.setMinIdle(minIdle);
        dataSource.setMaxActive(maxActive);
        dataSource.setMaxWait(maxWait);
        return dataSource;
    }
}

 

在控制器中注入數據源,調試即可查看是否注入相關的屬性值

@RestController
@RequestMapping(value = "hello")
public class HelloController {

    @Autowired
    private DataSource dataSource;

    @RequestMapping(value = "index")
    public String hello()
    {
        System.out.println(dataSource.toString());
        return "index";
    }
}

2.2、屬性方式

屬性讀取類

package rui.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "jdbc")
public class JdbcProperties {
    private String driverClassName;
    private String url;
    private String username;
    private String password;
    private int initialSize;
    private int minIdle;
    private int maxActive;
    private int maxWait;

    public String getDriverClassName() {
        return driverClassName;
    }

    public void setDriverClassName(String driver) {
        this.driverClassName = driver;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getInitialSize() {
        return initialSize;
    }

    public void setInitialSize(int initialSize) {
        this.initialSize = initialSize;
    }

    public int getMinIdle() {
        return minIdle;
    }

    public void setMinIdle(int minIdle) {
        this.minIdle = minIdle;
    }

    public int getMaxActive() {
        return maxActive;
    }

    public void setMaxActive(int maxActive) {
        this.maxActive = maxActive;
    }

    public int getMaxWait() {
        return maxWait;
    }

    public void setMaxWait(int maxWait) {
        this.maxWait = maxWait;
    }
}

 

配置類代碼,現在不需要通過@value去讀取每一個配置項目。

package rui.config;

import com.alibaba.druid.pool.DruidDataSource;
import jdk.nashorn.internal.objects.annotations.Property;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import javax.sql.DataSource;

/*數據庫配置類*/
@Configuration
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcConfig {

    @Bean
    public DataSource dataSource(JdbcProperties jdbcProperties) {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(jdbcProperties.getDriverClassName());
        dataSource.setUrl(jdbcProperties.getUrl());
        dataSource.setUsername(jdbcProperties.getUsername());
        dataSource.setPassword(jdbcProperties.getPassword());
        dataSource.setInitialSize(jdbcProperties.getInitialSize());
        dataSource.setMinIdle(jdbcProperties.getMinIdle());
        dataSource.setMaxActive(jdbcProperties.getMaxActive());
        dataSource.setMaxWait(jdbcProperties.getMaxWait());
        return dataSource;
    }
}
通過 @EnableConfigurationProperties(JdbcProperties.class) 來聲明要使用 JdbcProperties 數據讀取類
控制器內部代碼一樣,這種方式就是用屬性讀取類來讀取配置,不過屬性讀取類的屬性需要和類的屬性保持一致。

2.3、更優雅的注入

無需藉助jdbcProperties類,直接指定屬性前綴即可。
再次修改 JdbcConfig 類爲如下代碼:
@ConfigurationProperties(prefix = "jdbc")  聲明要注入的屬性前綴,Spring Boot會自動把相關屬性通過set方法注入到DataSource中,
@Configuration
public class JdbcConfig {
    @Bean
    @ConfigurationProperties(prefix = "jdbc")
    public DataSource dataSource() {
        return new DruidDataSource();
    }
}

3、Yaml配置文件

配置文件除了可以使用application.properties類型,還可以使用後綴名爲:.yml或者.yaml的類型,也就是:application.yml或者application.yaml
代碼格式:層層縮進方式
如果application.properties和application.yml都存在。
會把兩個文件的配置合併,如果有重複屬性,以properties中的爲準。
如果是配置數組、list、set等結構的內容,那麼在yml文件中格式爲:
key:
- value1
- value2

3.1、多個yaml文件

當一個項目中有多個yml配置文件的時候,可以以application-**.yml命名;在application.yml中配置項目使用激活這些配置文件即可。

 

  

4、自動配置原理

使用Spring Boot之後,一個整合了SpringMVC的WEB工程開發,變的無比簡單,那些繁雜的配置都消失不見了,這是如何做到的?一切魔力的開始,都是從我們的main函數來的,所以我們再次來看下啓動類:

我們發現類上邊有註解:@SpringBootApplication,進入源碼查看:

SpringBootConfifiguration源碼

通過這段我們可以看出,在這個註解上面,又有一個 @Configuration 註解。通過上面的註釋閱讀我們知道:這個註解的作用就是聲明當前類是一個配置類,然後Spring會自動掃描到添加了 @Configuration 的類,並且讀取其中的配置信息。而 @SpringBootConfiguration 是來聲明當前類是SpringBoot應用的配置類,項目中只能有一個。所以一般我們無需自己添加。

@EnableAutoConfifiguration

第二級的註解 @EnableAutoConfiguration ,告訴Spring Boot基於你所添加的依賴,去“猜測”你想要如何配置Spring。比如我們引入了 spring-boot-starter-web ,而這個啓動器中幫我們添加了 tomcat 、 SpringMVC的依賴。此時自動配置就知道你是要開發一個web應用,所以就幫你完成了web及SpringMVC的默認配置了!

所以,我們使用SpringBoot構建一個項目,只需要引入所需框架的依賴,配置就可以交給SpringBoot處理了。除非你不希望使用SpringBoot的默認配置,它也提供了自定義配置的入口。

@ComponentScan 

配置組件掃描的指令。提供了類似與 <context:component-scan> 標籤的作用通過basePackageClasses或者basePackages屬性來指定要掃描的包。如果沒有指定這些屬性,那麼將從聲明這個註解的類所在的包開始,掃描包及子包

 

而我們的@SpringBootApplication註解聲明的類就是main函數所在的啓動類,因此掃描的包是該類所在包及其子包。因此,一般啓動類會放在一個比較前的包目錄中。

5、自動配置修改方案

SpringBoot爲我們提供了默認配置,而默認配置生效的步驟:

  1. @EnableAutoConfiguration註解會去尋找 META-INF/spring.factories 文件,讀取其中以
  2. EnableAutoConfiguration 爲key的所有類的名稱,這些類就是提前寫好的自動配置類
  3. 這些類都聲明瞭 @Configuration 註解,並且通過 @Bean 註解提前配置了我們所需要的一切實例
  4. 但是,這些配置不一定生效,因爲有 @ConditionalOn 註解,滿足一定條件纔會生效。比如條件之一: 是一些 相關的類要存在
  5. 類要存在,我們只需要引入了相關依賴(啓動器),依賴有了條件成立,自動配置生效。
  6. 如果我們自己配置了相關Bean,那麼會覆蓋默認的自動配置的Bean
  7. 我們還可以通過配置application.yml文件,來覆蓋自動配置中的屬性

1)啓動器

所以,我們如果不想配置,只需要引入依賴即可,而依賴版本我們也不用操心,因爲只要引入了SpringBoot提供的starter(啓動器),就會自動管理依賴及版本了。因此,玩SpringBoot的第一件事情,就是找啓動器,SpringBoot提供了大量的默認啓動器

2)全局配置

另外,SpringBoot的默認配置,都會讀取默認屬性,而這些屬性可以通過自定義 application.properties 文件來進行覆蓋。這樣雖然使用的還是默認配置,但是配置中的值改成了我們自定義的。因此,玩SpringBoot的第二件事情,就是通過 application.properties 來覆蓋默認屬性值,形成自定義配置。我們需要知道SpringBoot的默認屬性key,非常多,可以再idea中自動提示

默認配置的組件很多:

6、自動配置修改例子

 

 

 

 

 

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