springboot创建和实现原理
项目的创建
-
普通的maven项目
需要导入依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
创建启动类
在java包下创建一个启动类,这个类需要加@SpringBootApplication这注解,这个注解是启动springboot项目的关键,无需tomcat启动。
-
spring Initialzr
idea已经配置好依赖和启动类
自动配置
进入@SpringBootApplication
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
@SpringBootConfiguration里面有@Configuration指定这类是一个配置类
@ComponentScan自动扫描组件,扫描主类所在的同级包以及下级包里的Bean
@EnableAutoConfiguration是最关键的一个注解,进入里面
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
进入@AutoConfigurationPackage后发现一个注解@Import(Registrar.class),再次点击进去Registrar后发现registerBeanDefinitions方法,可以得到一个结果集,这个结果集来自于@EnableAutoConfiguration加载路径下的所有的META-INF/spring.factories。
@Import(AutoConfigurationImportSelector.class)进入后
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);
}
过滤一些不需要的AnnotationMetadata。
注意源码里面的@Conditional子类注解:
@ConditionalOnBean:当容器里有指定Bean的条件下
@ConditionalOnClass:当类路径下有指定的类的条件下
@ConditionalOnExpression:基于SpEL表达式为true的时候作为判断条件才去实例化
@ConditionalOnJava:基于JVM版本作为判断条件
@ConditionalOnJndi:在JNDI存在的条件下查找指定的位置
@ConditionalOnMissingBean:当容器里没有指定Bean的情况下
@ConditionalOnMissingClass:当容器里没有指定类的情况下
@ConditionalOnWebApplication:当前项目时Web项目的条件下
@ConditionalOnNotWebApplication:当前项目不是Web项目的条件下
@ConditionalOnProperty:指定的属性是否有指定的值
@ConditionalOnResource:类路径是否有指定的值
@ConditionalOnOnSingleCandidate:当指定Bean在容器中只有一个,或者有多个但是指定首选的Bean
思维图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k3lGV8w1-1632639658601)(https://www.pianshen.com/images/811/cf788605c99935a452b7ed997ed9c99b.png)]
总结
自动配置是springboot启动时,通过@EnableAutoConfiguration加载路径下的所有的META-INF/spring.factories,加载列表里的自动配置类都以AutoConfiguration结尾,用注解@EnableConfigurationProperties实现绑定,之后根据一些@Conditional条件,决定是否自动配置,还是用开发者自定义的。