目录
@SpringBootApplication其中的三个重要注解
前言
初次搭SpringBoot环境的时候,一看到项目搭起来就不得不惊叹前辈大牛的牛x之处。习惯了SSM的繁琐操作之后,使用SpringBoot无需各种POM坐标,只要just run就能跑起来。
SpringBoot的核心就是自动配置,所以今天刚好有空就来看看SpringBoot到底是如何实现自动配置的。
一、SpringBoot的自动配置原理
Springboot的自动配置是通过 SpringBootApplication 注解实现的。
@SpringBootApplication
@SpringBootApplication
public class Application {
public static void main(String[] args) {SpringApplication.run(Application .class, args);}
}
点进去可以看到它其中我们比较看重的功能实际上由三个注解组成。
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
@SpringBootApplication其中的三个重要注解
- @EnableAutoConfiguration
- @ComponentScan
- @SpringBootConfiguration
@EnableAutoConfiguration是开启自动配置功能的,下面再详细讲。
@ComponentScan 注解,则是用于扫描被 Component 注解的类(以当前类(Application类启动类)所在的包为基包递归扫描),这个在之前SSM项目中就已经见过很多遍了
@SpringBootConfiguration,根据Spring文档,@SpringBootConfiguration是Spring标准@Configuration批注的替代方法。区别在于@SpringBootConfiguration允许自动找到配置。
重点来看看@EnableAutoConfiguration
@EnableAutoConfiguration是springboot实现自动化配置的核心注解
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
可以看到
@EnableAutoConfiguration通过@Import注入了一个ImportSelector的实现类,筛选了哪些是需要自动配置的。
继续点进去看
/** * Return the auto-configuration class names that should be considered. By default * this method will load candidates using {@link SpringFactoriesLoader} with * {@link #getSpringFactoriesLoaderFactoryClass()}. * @param metadata the source metadata * @param attributes the {@link #getAttributes(AnnotationMetadata) annotation * attributes} * @return a list of candidate configurations */ 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; }其中有一个getCandidateConfigurations方法,很明显springboot是通过它加载了spring factories
@Override public String[] selectImports(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata); return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); } protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } AnnotationAttributes attributes = getAttributes(annotationMetadata); List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); configurations = removeDuplicates(configurations); Set<String> exclusions = getExclusions(annotationMetadata, attributes); checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = getConfigurationClassFilter().filter(configurations); fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationEntry(configurations, exclusions); }通过这一行
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);spring boot扫描了META-INF/spring.factories文件
————————————————
二、SpringBoot自动配置相关
再看看mybatis是怎么通过starter依赖自动配置的
spring.factories文件中记录着自动配置类AutoConfigurationClass
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mybatis.spring.boot.autoconfigure.MybatisLanguageDriverAutoConfiguration,\
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
继续往下我们看到了
@EnableConfigurationProperties(MybatisProperties.class)
public class MybatisAutoConfiguration implements InitializingBean {
private final MybatisProperties properties;
这个MybatisProperties怎么看都和新建项目就有的application.properties很像吧,继续点进去看
@ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX)
public class MybatisProperties {
public static final String MYBATIS_PREFIX = "mybatis";
private static final ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
/**
* Location of MyBatis xml config file.
*/
private String configLocation;
/**
* Locations of MyBatis mapper files.
*/
private String[] mapperLocations;
/**
* Packages to search type aliases. (Package delimiters are ",; \t\n")
*/
private String typeAliasesPackage;
原来这些configLocation,typeAliasesPackage等等就是我们在application.properties中给mybatis中配置的属性。
总结
Spring boot真好用
本文深入剖析SpringBoot的自动配置原理,从@SpringBootApplication入手,详细解读@EnableAutoConfiguration、@ComponentScan和@SpringBootConfiguration的作用及其实现机制,并以MyBatis为例说明starter依赖自动配置的过程。
2320

被折叠的 条评论
为什么被折叠?



