SpringBoot - 02 配置方式

在入门案例中,我们没有任何的配置,就可以实现一个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中自动提示

在spring-Boot-AutoConfigure组件内有一个spring.factories,这个文件中定义了一些自动配置的类,也包含了很多的内置自动配置组件。

6、自动配置修改例子

 以WebMVC为例介绍,

导航进入这个类的源代码:

 在文件中找属性配置类

也可以通过组件目录内中找到属性配置文件:

 

进入属性配置类,找到配置前缀和相关的配置属性。

内部包含内部类View,用来配置视图前缀和后缀的。

在xml里边是这样的:

 

 通过application.yaml文件进行配置修改,将默认的配置属性值修改成自己的内容。

 

 大致步骤总结:

 

 

 

 

 

posted @ 2022-02-16 19:30  草莓爸  阅读(67)  评论(0编辑  收藏  举报