当你使用SpringBoot创建项目的时候,你会惊讶的发现它基本没有什么配置文件,也能够正常的运作。那可能就会冒出两个问题,它是如何把自己编写的代码加载到Spring容器的呢?又是如何加载第三方依赖的呢?与传统的做法(不使用Springboot)又有什么区别呢?把我们自己编写的代码加载到Spring容器和加载第三方依赖都需要依赖@EnableAutoConfiguration注解,接下来就会对其进行简单的介绍。
@EnableAutoConfiguration注解
@EnableAutoConfiguration注解所在的位置
@EnableAutoConfiguration注解包含在@SpringBootApplication注解中,那么启动SpringBoot时,就会运行该注解
@EnableAutoConfiguration注解的作用
@EnableAutoConfiguration的作用使用把自己编写的业务代码加载到Spring容器和加载第三方依赖。该注解包含如下两个注解
- @AutoConfigurationPackage:使用SpringBoot自动配置,可以找到@SpringBootApplication所在类(主配置类)的位置,用来将主配置类所在包及其子包中的类加载到Spring容器
- @Import({AutoConfigurationImportSelector.class}):加载第三方依赖
@AutoConfigurationPackage注解
进入@AutoConfigurationPackage注解,显示如下。
进入Registarar类,断点模式,debug模式启动application,如下图所示:
通过@AutoConfigurationPackage可以确定@SpringBootApplication所在类(主配置类)所在的位置,用来将主配置类所在包及其子包中的类加载到spring容器。
SpringBoot加载自己编写的业务代码与传统做法的区别。
这里先确定位置,以后有时间再对该注解进行更加深入的了解研究。
@Import({AutoConfigurationImportSelector.class})注解
AutoConfigurationImportSelector加载第三方配置文件的时序图
加载第三方配置文件的代码位于SpringFactoriesLoader类中loadSpringFactories()方法中,部分源码如下:
SpringBoot在启动的时候,会根据META-INF/spring.factories找到第三方依赖,并将这些依赖引入本项目。该配置文件位于Spring-boot-autoconfiguration-xxx.jar包中。
上面的EnableAutoConfiguration配置了多个类,这些都是SpringBoot中自动配置相关类,在启动的过程中会解析对应的配置信息,每个Configuration类都定义相关bean的示例化配置。都说明了哪些bean可以被自动配置,什么条件自动配置,并把这些bean实例化出来。
Configuration类的自动装配,以org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration来说明。部分源码如下:
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties({ServerProperties.class})
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({CharacterEncodingFilter.class})
@ConditionalOnProperty(prefix = "server.servlet.encoding",value = {"enabled"},
matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
其中的
@Configuration(proxyBeanMethods = false):表明该类为配置类,会加载到SpringIOC容器中
@EnableConfigurationProperties({ServerProperties.class}):通过ServerProperties将编码类型设置为UTF-8(即自动装配为UTF-8)
满足@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({CharacterEncodingFilter.class})
@ConditionalOnProperty(prefix = "server.servlet.encoding",value = {"enabled"},matchIfMissing = true)这三个注解条件自动装配。否则不会自动装配。
我们可以看到自动化配置代码中有很多我们之前没有用到的注解配置,下面一一介绍。
@Configuration:这个配置就不用多做解释了,我们一直在使用
@EnableConfigurationProperties:这是一个开启使用配置参数的注解,value值就是我们配置实体参数映射的ClassType,将配置实体作为配置来源。
以下为SpringBoot内置条件注解:
@ConditionalOnBean:当SpringIoc容器内存在指定Bean的条件
@ConditionalOnClass:当SpringIoc容器内存在指定Class的条件
@ConditionalOnExpression:基于SpEL表达式作为判断条件
@ConditionalOnJava:基于JVM版本作为判断条件
@ConditionalOnJndi:在JNDI存在时查找指定的位置
@ConditionalOnMissingBean:当SpringIoc容器内不存在指定Bean的条件
@ConditionalOnMissingClass:当SpringIoc容器内不存在指定Class的条件
@ConditionalOnNotWebApplication:当前项目不是Web项目的条件
@ConditionalOnProperty:指定的属性是否有指定的值
@ConditionalOnResource:类路径是否有指定的值
@ConditionalOnSingleCandidate:当指定Bean在SpringIoc容器内只有一个,或者虽然有多个但是指定首选的Bean
@ConditionalOnWebApplication:当前项目是Web项目的条件
以上注解都是元注解@Conditional演变而来的,根据不用的条件对应创建以上的具体条件注解。
Configuration类有100多个,不可能全部自动装配,那如何知道SpringBoot开启了Configuration类哪些自动装配,禁止了哪些配置类的自动装配?
在application.properties中添加debug=true,在启动项目
日志中Positive matches:列表中的配置项表示springBoot开启了自动装配。
Negative matches列表中的配置项表示SpringBoot没有开启该配置类的自动装配
总结:本篇博客,主要是确定位置,对相关概念进行相应的了解,为之后深入学习研究打好基础
参考:颜渊老师教学视频
https://www.jianshu.com/p/5901da52ca09
https://blog.csdn.net/zjcjava/article/details/84028222
https://blog.csdn.net/u014745069/article/details/83820511