思考一下application.properties都能写哪些配置项,还有为什么可以写那么多的配置项,是不是觉得特别神奇呢。
分析自动配置原理
以RedisAutoConfiguration (redis相关自动配置)为例子来解释自动配置原理。 ```java // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) //
package com.addicated.demo.pojo;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
// 表明这是一个配置类,前面文章有提及过,进行spring的相关配置可以通过application文件 // 以及javaConfig配置类, // 加了这个注解的类就表明是一个配置类。 @Configuration(proxyBeanMethods = false)
// Spring底层@Conditional注解 // 根据不同的条件判断,如果满足指定的条件,整个配置类里面的配置就会生效 // 这里的含义是 RedisOperations 是否被声明,如果没有进行声明的话,这个配置类就不会生效 @ConditionalOnClass({RedisOperations.class}) // 启动指定类的ConfigurationProperties功能 // 进入 RedisProperties 查看,将配置文件中对应的值和 RedisProperties绑定起来 // 并吧 RedisProperties 加入到ioc中 @EnableConfigurationProperties({RedisProperties.class}) @Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class}) public class RedisAutoConfiguration { // 无餐构造方法 public RedisAutoConfiguration() { }
@Bean
@ConditionalOnMissingBean(
name = {"redisTemplate"}
)
// 条件为当 RedisConnectionFactory 该类被声明
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
// 给容器添加一个组建,这个组建的某些之需要从properties中获取
@Bean
@ConditionalOnMissingBean // 判断容器有没有这个组建
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
<a name="taCZC"></a>
## 一句话总结:根据当前不同的条件判断,决定这个配置累是否生效
- 一旦这个配置类生效;这个配置类就会给容器中添加各种组建
- 这些组建的属性是从对应的properties类中获取的,这些类中的每一个属性又是和配置文件绑定的
- 所有在配置文件中能配置的属性都是在xxxxProperties类中封装着
- 配置文件能配置什么就可以参照某个功能对应的这个属性类。
注意:这里我没有导入redis相关的依赖所以 RedisProperties 点不进去,使用一个其他的properties来进行表示
```java
//从配置文件中获取指定的值和bean的属性进行绑定
@ConfigurationProperties(prefix = "spring.http")
public class HttpProperties {
// .....
}
- 来到配置文件中试试前缀是否可提示
-
精髓
springboot启动会加载大量的自动配置类
- 那么如何知道哪些加载哪些没有加载呢? 在配置文件中 debug=true 之后在springboot应用启动的时候就可以根据日志推断哪些得到了加载哪些没有
- 进行开发的时候首先看自己需要的功能有没有在自动配置类当中
- 然后看看自动配置类中到底配置了哪些组件(只要需要的组建在其中,就不用再进行手动配置了)
- 给容器中自动配置类添加组建的时候,会从properties类中获取某些属性,只要在配置文件中指定这些属性的值即可。
xxxxAutoConfigurartion:自动配置类;给容器中添加组件
xxxxProperties:封装配置文件中相关属性
了解 @Conditional
了解完自动装配的原理后,关注一个细节问题,自动配置类必须在一定的条件下才能生效
@Conditional派生注解(Spring注解版原声的Conditional作用)
作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;
那么多的自动配置类,必须在一定的条件才能生效,也就是说,加载了这么多配置类,但不是所有的都生效了
如何知道哪些自动配置类生效?
- debug=true 来让控制台打印出来自动配置报告,这样就可以很方便的知道哪些自动配置类生效。
- Positive matches:(自动配置类启用的:正匹配)
Negative matches:(没有启动,没有匹配成功的自动配置类:负匹配)
Unconditional classes: (没有条件的类)