[springboot 学习3] 自定义配置

 

如何覆盖自动配置,使用自定义配置

要覆盖自动配置,可以就当自动配置不存在,直接显式地写一段配置。(可以是java, xml, groovy形式)

Spring Boot会发现你的配置,随后降低自动配置的优先级,以你的配置为准。

自定义配置的原理

  1. 大部分情况下,@ConditionalOnMissingBean注解是覆盖自动配置的关键。

例如:Spring Boot的DataSourceAutoConfiguration中定义的JdbcTemplate Bean

@Bean
@ConditionalOnMissingBean(JdbcOperations.class)
public JdbcTemplate jdbcTemplate(){
  return new JdbcTemplate(this.dataSource);
}

当不存在JdbcOperations类型(JdbcTemplate实现了该接口)的Bean时才生效。

Spring Boot的设计是加载应用级配置,随后再考虑自动配置类

  1. 还有通过一些@EnableXXX的注解实现的自定义配置。

例如:

@Configuration
@EnbaleConfigurationProperties
@ConditionalOnClass({EnableWebSecurity.class})
@ConditionalOnMissingBean(WebSecurityConfiguration.class)
@ConditionalOnWebApplication
public class SpringBootWebSecurityConfiguration{
}

这个security自动配置有多个条件,这里比较关注的是ConditionalOnClassConditionalOnMissingBeanConditionalOnClass要求classpath要有@EnableWebSecurity注解。 ConditionalOnMissingBean要求在没有WebSecurityConfiguration类型的bean时创建。表面上,我们自定义配置时没有这个bean,但通过在SecurityConfig(自定义的配置类)上添加@EnableWebSecurity注解,实际上间接创建了一个WebSecurityConfiguration的Bean。所以这个自动配置SpringBootWebSecurityConfiguration提供的配置被跳过了。

通过属性文件外置配置

只做了一点微调,为了不放弃自动配置,可以在环境变量JVM系统属性JNDI命令行参数属性文件中设置。

以关闭ascii-art banner(运行时,Spring的文字图标)为例:

  1. 执行jar时,命令行参数指定:
    java -jar demo-0.0.1-SNAPSHOT.jar --spring.main.banner-mode=off
    
  2. application.properties中指定配置:
    spring.main.banner-mode=off
    
  3. 设置环境变量
    export spring_main_banner_mode=off
    

各配置方式之间有优先级排序,高优先级会覆盖低优先级的相同属性。

Profile

配置文件

通过遵循application-{xxx}.properties/application-{xxx}.yml这种命名格式,就可以被spring boot自动读取。

[build.gradle]

dependencies {
	runtimeOnly 'com.h2database:h2'
	runtimeOnly 'mysql:mysql-connector-java'
}

多个配置文件

.
├── application-h2.properties
├── application-mysql.yml
└── application.properties

[application.properties]

spring.profiles.active=mysql
spring.jpa.show-sql=true

通过spring.profiles.active设置h2/mysql选择application-h2.properties/application-mysql.yml文件做配置。

[application-h2.properties]

spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb

[application-mysql.yml]

spring:
    datasource:
        url: jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_test
        username: root
        password: 123456
    jpa.hibernate.ddl-auto: update

单配置文件

[application.yml]

spring.profiles.active: h2
spring.jpa.show-sql: true

---

spring:
    profiles: h2
    h2.console.enabled: true
    datasource.url: jdbc:h2:mem:testdb

---

spring:
    profiles: mysql
    datasource:
        url: jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_test
        username: root
        password: 123456
    jpa.hibernate.ddl-auto: update

配置类

package com.yww.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Profile("production")
@Configuration
public class Config {
    
}