springboot自动配置

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot自动配置相关的知识,希望对你有一定的参考价值。

参考技术A 使用@Configuration 注解表明它是一个配置类,重要的是使用了@ConditionalOnClass注解,要求Classpath里必须要有DataSource和EmbeddedDatabaseType。如果它们不存在,条件就不成立,DataSourceAutoConfiguration提供的配置都会被忽略掉。DataSourceAutoConfiguration 中定义的JdbcTemplate Bean中演示了@ConditionalOnMissingBean注解是如何工作的
@Bean
@ConditionalOnMissingBean(JdbcOperations.class)
public JdbcTemplate jdbcTemplate()
return new JdbcTemplate(this.dataSource);

dbcTemplate()方法上添加了@Bean注解,在需要时可以配置出一个JdbcTemplateBean。但它上面还加了@ConditionalOnMissingBean注解,要求当前不存在JdbcOperations类型(JdbcTemplate实现了该接口)的Bean时才生效,如果有了该接口的实现Bean,则不会创建。
怎么覆盖掉自动化配置?什么时候出现JdbcOperations类型的Bean?
SpringBoot的设计是加载应用级别的配置,如果应用级别没有,则在考虑自动化的配置,如果我们我们自己定义一个JdbcTemplate,那么就会忽略掉自动化配配配置。

如何覆盖一些需要微调的自动化配置?
通过属性文件外置配置
当我们只需要微调一些细节的时候,比如端口号,设置数据库得Url,我们可以通过只环境变量、 Java系统属性、 JNDI(Java Naming and Directory Interface)、命令行参数或者属性文件里进行指定就好了。 Spring Boot应用程序有多种设置途径。 Spring Boot能从多种属性源获得属性,包括如下几处。
(1) 命令行参数
(2) java:comp/env里的JNDI属性
(3) JVM系统属性
(4) 操作系统环境变量
(5) 随机生成的带random.*前缀的属性(在设置其他属性时,可以引用它们,比如$random.
long)
(6) 应用程序以外的application.properties或者appliaction.yml文件
(7) 打包在应用程序内的application.properties或者appliaction.yml文件
(8) 通过@PropertySource标注的属性源
(9) 默认属性
这个列表 按照优先级排序,也就是说,任何在高优先级属性源里设置的属性都会覆盖低优先级的相同属性,例如,命令行参数会覆盖其他属性源里的属性。application.properties和application.yml文件能放在以下四个位置。
(1) 外置,在相对于应用程序运行目录的/config子目录里。
(2) 外置,在应用程序运行的目录里。
(3) 内置,在config包内。
(4) 内置,在Classpath根目录
同样,这个列表按照优先级排序。也就是说,相对于应用程序运行目录 /config子目录里的application.properties会覆盖应用程序Classpath里的application.properties中的相同属性。
此外,如果你在同一优先级位置同时有application.properties和application.yml,那么application.
yml里的属性会覆盖application.properties里的属性。

SpringBoot05:自动配置原理

SpringBoot05:自动配置原理

自动配置原理

配置文件到底能写什么?怎么写?

SpringBoot官方文档中有大量的配置,我们无法全部记住

分析自动配置原理

我们以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理;

//表示这是一个配置类,和以前编写的配置文件一样,也可以给容器中添加组件;
@Configuration 

//启动指定类的ConfigurationProperties功能;
  //进入这个HttpProperties查看,将配置文件中对应的值和HttpProperties绑定起来;
  //并把HttpProperties加入到ioc容器中
@EnableConfigurationProperties({HttpProperties.class}) 

//Spring底层@Conditional注解
  //根据不同的条件判断,如果满足指定的条件,整个配置类里面的配置就会生效;
  //这里的意思就是判断当前应用是否是web应用,如果是,当前配置类生效
@ConditionalOnWebApplication(
    type = Type.SERVLET
)

//判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;
@ConditionalOnClass({CharacterEncodingFilter.class})

//判断配置文件中是否存在某个配置:spring.http.encoding.enabled;
  //如果不存在,判断也是成立的
  //即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;
@ConditionalOnProperty(
    prefix = "spring.http.encoding",
    value = {"enabled"},
    matchIfMissing = true
)

public class HttpEncodingAutoConfiguration {
    //他已经和SpringBoot的配置文件映射了
    private final Encoding properties;
    //只有一个有参构造器的情况下,参数的值就会从容器中拿
    public HttpEncodingAutoConfiguration(HttpProperties properties) {
        this.properties = properties.getEncoding();
    }
    
    //给容器中添加一个组件,这个组件的某些值需要从properties中获取
    @Bean
    @ConditionalOnMissingBean //判断容器没有这个组件?
    public CharacterEncodingFilter characterEncodingFilter() {
        CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
        filter.setEncoding(this.properties.getCharset().name());
        filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));
        filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));
        return filter;
    }
    //。。。。。。。
}

一句话总结 :根据当前不同的条件判断,决定这个配置类是否生效!

  • 一但这个配置类生效;这个配置类就会给容器中添加各种组件;
  • 这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
  • 所有在配置文件中能配置的属性都是在xxxxProperties类中封装着;
  • 配置文件能配置什么就可以参照某个功能对应的这个属性类
//从配置文件中获取指定的值和bean的属性进行绑定
@ConfigurationProperties(prefix = "spring.http") 
public class HttpProperties {
    // .....
}

我们去配置文件里面试试前缀,看提示!

这就是自动装配的原理!

精髓

1、SpringBoot启动会加载大量的自动配置类

2、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;

3、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)

4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;

xxxxAutoConfigurartion:自动配置类;给容器中添加组件

xxxxProperties:封装配置文件中相关属性;

了解:@Conditional

了解完自动装配的原理后,我们来关注一个细节问题,自动配置类必须在一定的条件下才能生效;

@Conditional派生注解(Spring注解版原生的@Conditional作用)

作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;

那么多的自动配置类,必须在一定的条件下才能生效;也就是说,我们加载了这么多的配置类,但不是所有的都生效了。

我们怎么知道哪些自动配置类生效?

我们可以通过启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;

#开启springboot的调试类
debug=true

Positive matches:(自动配置类启用的:正匹配)

Negative matches:(没有启动,没有匹配成功的自动配置类:负匹配)

Unconditional classes: (没有条件的类)

【演示:查看输出的日志】

掌握吸收理解原理,即可以不变应万变!

以上是关于springboot自动配置的主要内容,如果未能解决你的问题,请参考以下文章

boot自动配置的原理

SpringBoot05:自动配置原理

SpringBoot自动配置原理

SpringBoot——SpringBoot入门SpringBoot的自动配置配置文件和开发小技巧

SpringBoot自动配置的实现原理

springboot自动配置