一、首先要知道springboot的启动类
然后知道启动类有一个重要的注解:@SpringBootApplication
然后跟踪查看,它是由@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan注解组成的
@SpringBootConfiguration作用是声明当前类是一个组件
@ComponentScan作用是扫描启动类包下面的所有组件
@EnableAutoConfiguration作用是自动装配所有的bean
@EnableAutoConfiguration源码追踪
可以看到导入啦自动装配的类@Import(AutoConfigurationImportSelector.class)
然后进一步看它实现啦这个接口DeferredImportSelector.java,
并且重写String[] selectImports(AnnotationMetadata annotationMetadata)方法:
再看接口DeferredImportSelector.java继承了ImportSelector.java接口,然而ImportSelector接口有一个重要的方法String[] selectImports(AnnotationMetadata importingClassMetadata);它正好是上面AutoConfigurationImportSelector.java重写过的方法
那么我们回过头来看这个重写的方法,方法体有获取自动自动装配的方法
getAutoConfigurationEntry(annotationMetadata),再看这个方法中调用啦返回应考虑的自动配置类名称getCandidateConfigurations(annotationMetadata, attributes);
继续追代码调用SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
继续追代码:调用这个方法loadSpringFactories
继续追代码:加载了配置类的资源META-INF/spring.factories
继续查看这个资源
这下面能被扫描到资源,按照要开启自动装配,并且在类路径中存在bean就会被装载
例如:jdbc下面的包DataSourceAutoConfiguration.java
它会自动扫描properties文件或者yml文件,根据文件下你设置的数据库配置自动装配
注意:理解一下这几个注解
@ConditionalOnBean:当容器里有指定 Bean 的条件下
@ConditionalOnMissingBean:当容器里没有指定 Bean 的情况下
@ConditionalOnSingleCandidate:当指定 Bean 在容器中只有一个,或者虽然有多个但是指定首选 Bean
@ConditionalOnClass:当类路径下有指定类的条件下
@ConditionalOnMissingClass:当类路径下没有指定类的条件下
@ConditionalOnProperty:指定的属性是否有指定的值
@ConditionalOnResource:类路径是否有指定的值
@ConditionalOnExpression:基于 SpEL 表达式作为判断条件
@ConditionalOnJava:基于 Java 版本作为判断条件
@ConditionalOnJndi:在 JNDI 存在的条件下差在指定的位置
@ConditionalOnNotWebApplication:当前项目不是 Web 项目的条件下
@ConditionalOnWebApplication:当前项目是 Web 项 目的条件下