SpringBoot
SpringBoot是Java利用的开发框架,基于Spring4.0设计,继承了Spring框架原有的优良个性,还并通过简化配置来进一步优化了Spring利用的整个搭建和开发过程,SpringBoot通过集成大量的框架,很好的解决了依赖包版本抵触,以及援用不稳定性等问题
SpringBoot 个性
- 创立独立的Spring利用
- 内嵌Tomcat或Jetty等Servlet容器,利用打包后即可间接运行
- 提供一系列预设配置来简化配置
- 尽可能主动配置Spring容器与三方类库
- 提供可用于生产的个性,如度量、运行状况检查和内部化配置
- 不须要代码生成,不须要XML配置
主动拆卸
主动拆卸是为了从spring.factories文件中获取到对应须要进行主动拆卸的类,并生成相应的Bean对象,而后将它们交给spring容器来治理嘛,主动拆卸是 SpringBoot 的外围,咱们只有引入一个 starter 组件依赖就能实现主动拆卸
依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.3</version> <relativePath/> <!-- lookup parent from repository --></parent>
启动类
@SpringBootApplicationpublic class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }}
@SpringBootApplication
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })public @interface SpringBootApplication { // 内容省略}
由源码可知,@SpringBootApplication理论是由3个要害的注解组成
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan
@SpringBootConfiguration
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Configuration@Indexedpublic @interface SpringBootConfiguration { // 内容省略}
由源码可知,@SpringBootConfiguration 实际上就是一个 @Configuration 注解,就是为了让以后类作为一个配置类交由 Spring 的 IOC 容器进行治理
@ComponentScan
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE})@Documented@Repeatable(ComponentScans.class)public @interface ComponentScan { // 内容省略}
由源码可知,@ComponentScan 等价于在 xml 文件中配置 context:component-scan,SpringBoot 会默认扫描以后类所在的包及其子包中的所有标注了 @Component,@Service,@Controller 等注解的类
@EnableAutoConfiguration
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage@Import(AutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration { // 内容省略}
由源码可知,@EnableAutoConfiguration 是由 @AutoConfigurationPackage 与 @Import 组成的注解,而AutoConfigurationImportSelector正是主动拆卸的外围;AutoConfigurationImportSelector实现了顶层接口ImportSelector,在selectImports办法中,首先判断SpringBoot是否开启主动配置,如开启则进一步获取须要主动拆卸的类
@Overridepublic 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);}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;}
其中的重点就在SpringFactoriesLoader.loadFactoryNames这一行代码中
public final class SpringFactoriesLoader {/** * The location to look for factories. * <p>Can be present in multiple JAR files. */public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);static final Map<ClassLoader, Map<String, List<String>>> cache = new ConcurrentReferenceHashMap<>();private SpringFactoriesLoader() {}
至此已能够看出,为何SpringBoot的依赖中会存在.factories文件,loadFactoryNames 办法会去 META-INF/spring.factories 文件中依据 EnableAutoConfiguration 的全限定类名获取到咱们须要导入的类,而 EnableAutoConfiguration 类的全限定类名为
org.springframework.boot.autoconfigure.EnableAutoConfiguration
@AutoConfigurationPackage
@AutoConfigurationPackage 注解会将增加该注解的类所在的 package 作为主动配置 package 进行治理,也就是说当SpringBoot利用启动时,默认会将启动类所在的package作为主动配置的package
总结
- SpringBoot 是基于 Spring 的框架
- SpringBoot 预置了许多依赖,并简化了 Spring 原有的配置,使开发更加简略快捷
- SpringBoot 通过 AutoConfigurationImportSelector 与 META-INF/spring.factories 省去了一些类的配置过程,实现了主动拆卸