SpringBoot - 02 配置方式
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;
}
}
2.3、更优雅的注入
@Configuration
public class JdbcConfig {
@Bean
@ConfigurationProperties(prefix = "jdbc")
public DataSource dataSource() {
return new DruidDataSource();
}
}

3、Yaml配置文件

3.1、多个yaml文件
当一个项目中有多个yml配置文件的时候,可以以application-**.yml命名;在application.yml中配置项目使用激活这些配置文件即可。

4、自动配置原理
使用Spring Boot之后,一个整合了SpringMVC的WEB工程开发,变的无比简单,那些繁杂的配置都消失不见了,这是如何做到的?一切魔力的开始,都是从我们的main函数来的,所以我们再次来看下启动类:

我们发现类上边有注解:@SpringBootApplication,进入源码查看:


通过这段我们可以看出,在这个注解上面,又有一个 @Configuration 注解。通过上面的注释阅读我们知道:这个注解的作用就是声明当前类是一个配置类,然后Spring会自动扫描到添加了 @Configuration 的类,并且读取其中的配置信息。而 @SpringBootConfiguration 是来声明当前类是SpringBoot应用的配置类,项目中只能有一个。所以一般我们无需自己添加。
第二级的注解 @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为我们提供了默认配置,而默认配置生效的步骤:
- @EnableAutoConfiguration注解会去寻找 META-INF/spring.factories 文件,读取其中以
- EnableAutoConfiguration 为key的所有类的名称,这些类就是提前写好的自动配置类
- 这些类都声明了 @Configuration 注解,并且通过 @Bean 注解提前配置了我们所需要的一切实例
- 但是,这些配置不一定生效,因为有 @ConditionalOn 注解,满足一定条件才会生效。比如条件之一: 是一些 相关的类要存在
- 类要存在,我们只需要引入了相关依赖(启动器),依赖有了条件成立,自动配置生效。
- 如果我们自己配置了相关Bean,那么会覆盖默认的自动配置的Bean
- 我们还可以通过配置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文件进行配置修改,将默认的配置属性值修改成自己的内容。

大致步骤总结:


浙公网安备 33010602011771号