SpringBootApplication注解大解密

SpringBootApplication注解大解密

SpringBootApplication注解

SpringBootApplication注解是一个符合注解,集成了

@SpringBootConfiguration

@EnableAutoConfiguration

@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),

@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })

也就是说这一个注解集成了三个注解的功能。

@SpringBootConfiguration注解的作用

可以看到SpringbootConfiguration注解继承了Configuration注解,这个注解的作用也就很明确了。

把主启动类也当成是配置类,这也是我们能够在著启动类以@Bean的形式向IOC容器注册bean对象。

@EnableAutoConfiguration

EnabeleAutoConfiguration是实现自动配置的关键。

我们首先分析一下@Import(AutoConfigurationImportSelector.class),@Import的可以向IOC容器注册对象,也可以通过导入ImportSelector的实现类间接向IOC容器导入对象,或者导入BeanDefinitionRegister实现向IOC容器导入对象。

@Import(AutoConfigurationImportSelector.class)其实是向IOC容器注册了一个AutoConfigurationImportSelector对象,

AutoConfigurationImportSelector.selectImports方法返回一个String\[\],同时也会把String\[\]里的对象加入到IOC容器中。

分析下selectImports做了什么事情。

java 复制代码
//selectImports是接口ImportSelector定义的方法
@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);
	}
	protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
	//Spring SPI机制加载spring.factories文件中EnableAutoConfiguration的实现类
		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;
	}
	protected Class<?> getSpringFactoriesLoaderFactoryClass() {
		return EnableAutoConfiguration.class;
	}

我们再来看下这个spring.factories文件是什么内容。

看到一些熟悉的内容了把,其实就是很多配置文件。

java 复制代码
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\

打个断点验证一下

接着分析@AutoConfigurationPackage的作用是什么。

核心作用是标记并注册 Spring Boot 启动类所在的包为「自动配置包」,让 Spring 能扫描到该包及其子包下的自定义组件(如 @Controller、@Service、@Repository 等)

java 复制代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage

这个注解也用到了Import注解,所以这个Import注解也是相当的重要。

AutoConfigurationPackages.Registrar是ImportBeanDefinitionRegistrar的一个实现类可以向IOC容器定义BeanDefinition信息。

可以看到这个导入的包名就是启动类所在的包名,这也就解释了主启动类默认扫描主启动类所在包以及子包的所有组件。

ComponentScan注解

这个注解就不再过多描述了

总结

主启动类白哦住SpringBootApplication其实是

@SpringBootConfiguration

@EnableAutoConfiguration

@ComponentScan

@SpringBootConfiguration相当于@Configuration,标注启动类为配置类。

@EnableAutoConfiguration自动装配我们要扩展的组件以及设置basePackage

@ComponentScan扫描。扫描主启动类所在包以及子包的所有组件。

相关推荐
星辰徐哥6 小时前
Spring Boot 微服务架构设计与实现
spring boot·后端·微服务
星辰徐哥6 小时前
Spring Boot 数据导入导出与报表生成
spring boot·后端·ui
明夜之约6 小时前
Spring Boot 自动装配源码
java·spring boot·后端
Leaton Lee6 小时前
Spring Boot分层架构详解:从Controller到Service再到Mapper的完整流程
java·spring boot·后端·架构
Micro麦可乐7 小时前
Spring Boot 实战:从零设计一个短链系统(含完整代码与数据库设计)
数据库·spring boot·后端·哈希算法·雪花算法·短链系统
Jinkxs7 小时前
Resilience4j- 与 Spring Boot 快速集成:自动配置与基础注解使用
java·spring boot·后端
毕设源码_郑学姐7 小时前
计算机毕业设计springboot网络相册设计与实现 基于Spring Boot框架的在线相册管理系统开发与应用 Spring Boot驱动的网络影集设计与实践
spring boot·后端·课程设计
辣机小司7 小时前
【踩坑记录:Spring Boot 配置文件读取值不一致?警惕 YAML 的“八进制陷阱”与 SnakeYAML 版本之谜】
java·spring boot·后端·yaml·踩坑记录
一条小锦吕*7 小时前
基于Spring Boot + 数据可视化 + 协同过滤算法的推荐系统设计与实现(源码+论文+部署全讲解)
spring boot·算法·信息可视化
Jinkxs7 小时前
Prometheus - 监控微服务:Spring Boot 应用指标暴露与监控
spring boot·微服务·prometheus