springboot自动配置原理
自动配置:
pom.xml
- 代码解读
- 复制代码
spring-boot-dependencies 核心依赖在父工程中
- 我们在写或者引入一些springboot依赖时,不需要指定版本,就因为有这些版本仓库
starter
- 就是springboot的启动场景
- 比如spring-boot-starter-web,他就会帮我们自动导入web环境所有的依赖
- springboot会将所有的场景都变成一个个的启动器
- 我们要使用什么功能,引入相应的启动器就可以了
主程序
css
- 代码解读
- 复制代码
@SpringBootApplication 标注是一个springboot的应用
less
- 代码解读
- 复制代码
@SpringBootConfiguration springboot的配置
@Configuration spring的配置类
@Component 说明这也是一个spring的组件
@EnableAutoConfiguration 开启自动配置
@AutoConfigurationPackage 自动配置包
@Import(AutoConfigurationPackages.Registrar.class) 导入选择器
@Import(AutoConfigurationImportSelector.class) 导入选择器
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); 获取所有的配置
typescript
- 代码解读
- 复制代码
//获取所有的配置
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
bash
- 代码解读
- 复制代码
META-INF/spring.factories 自动配置的核心文件
这个文件里放的全是自动配置类的名称,主程序启动时就通过注解将这些自动类配置类全部加载,有了这些配置类,就省去我们写配置文件
java
- 代码解读
- 复制代码
为什么加载了很多自动配置类 一些生效了,一些没生效,以springmvc的自动配置类来示例:
下面这个是springmvc的自动配置类
@Configuration 表示这是一个配置类
@ConditionalOnClass 这个判断条件成立才会加载这个配置类,也就是说Servlet,DispatcherServlet存在才生效,我们建项目时导入mvc包那么这个配置类才生效
@ConditionalOnWebApplicatio 当前是个web程序时才生效
其他的配置类类似 都是在配置类上通过注解判断是否生效
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
public static final String DEFAULT_PREFIX = "";
public static final String DEFAULT_SUFFIX = "";
private static final String[] SERVLET_LOCATIONS = { "/" };
@Bean
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter();
}
ini
- 代码解读
- 复制代码
springboot中redis的配置文件如下
spring.redis.host=127.0.0.1
spring.redis.port=6379
我们可以通过@ConfigurationProperties 将它们注入到一个类中去,也可以用@value单个绑定,配置文件方式写更便捷,类过于麻烦,那这个配置文件中能写那些东西呢?
dart
代码解读
复制代码
这是redis的自动配置类
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class) 自动配置属性,以RedisProperties类为准
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
arduino
代码解读
复制代码
这是RedisProperties类
可以看到@ConfigurationProperties,说明将配置文件的值注入进来,也可以看到前缀spring.redis 和redis的配置文件的一摸一样,如配置主机配置文件就可以写spring.redis.host="localhost",下面这个类host属性有个默认的值localhost,所以我们不在配置文件中配置redis的连接地址,你也能连上以本地的redis,所以你在配置文件里配置了springboot就用你的,你没配置就用配置类默认的,同理我们再配置其他属性时,都可以参考响应的配置类编写配置文件
@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
/**
* Database index used by the connection factory.
*/
private int database = 0;
/**
* Connection URL. Overrides host, port, and password. User is ignored. Example:
* redis://user:password@example.com:6379
*/
private String url;
/**
* Redis server host.
*/
private String host = "localhost";
总结:springboot自动配置可以理解为,springboot的主程序在运行时,通过@EnableAutoConfiguration开启自动配置,首先会去扫描META-INF/spring.factories下所有的自动配置类,有了这些配置类就省去我们写配置文件,通过@ConditionalXXX判断这些配置类是否应该生效,只要导入了对应的starter,自动配置就会生效,通过相对应配置类上的@EnableConfigurationProperties,加载相关配置属性,若配置文件中有的就用配置文件的,没有的就用默认提供的,这就是springboot的自动配置原理。