当前位置:   article > 正文

Spring Boot——源码解析总结_springboot博客代码如何理解

springboot博客代码如何理解

一、常见注解

# 使用 Spring 快速注册 @ConfigurationProperties 注释的 bean 的便捷方法。
# 无论这个值如何(value属性的值),标准 Spring Beans 也将被扫描(注册进IoC容器中)。
# 默认注册的 bean 的 id 格式为:@ConfigurationProperties属性prefix的值-类名全限定名( student-com.ccbx.pojo.Student )
@EnableConfigurationProperties(value = {Student.class})

#仅仅在当前上下文中存在某个对象时,才会实例化一个Bean
@ConditionalOnBean

#某个class位于类路径上(或引入jar包的根目录下),才会实例化一个Bean
@ConditionalOnClass

#该注解来控制@Configuration是否生效.
# prefix :为application.yml配置文件中的前缀,
# name :为application.yml配置文件中的属性的名字
# havingValue :name属性的值与配置的值对比值,当两个值相同返回true,配置类生效;反之不生效
@ConditionalOnProperty

#当表达式为true的时候,才会实例化一个Bean
@ConditionalOnExpression

#仅仅在当前上下文中不存在某个类型的对象(name属性指定bean的名称)时,
# 该注解修饰的带有@Bean注解的方法才会执行,才会实例化一个Bean
@ConditionalOnMissingBean(name = "exampleBean")

#某个class类路径上不存在的时候,才会实例化一个Bean
@ConditionalOnMissingClass
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

二、Spring Boot 的自动配置原理

2.1、流程分析

Spring Boot 的启动类

/**
 * Spring Boot的启动类
 * 【要运行SpringBoot提供的启动引导类,SpringBoot才可以进行访问】
 */
@SpringBootApplication
public class SpringbootDemoApplication {
    public static void main(String[] args) {
        //作用:可用于从 Java 主方法引导和启动 Spring 应用程序的类。
        //默认情况下,类将执行以下步骤来引导您的应用程序:
        //  1、创建一个合适的ApplicationContext实例(取决于你的类路径)
        //  2、注册CommandLinePropertySource以将命令行参数公开为 Spring 属性
        //  3、刷新应用程序上下文,加载所有单例 bean
        //  4、触发任何CommandLineRunner bean
        SpringApplication.run(SpringbootDemoApplication.class, args);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

@SpringBootApplication 注解源码

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
//表示一个类提供了 Spring Boot 应用程序@Configuration 。
@SpringBootConfiguration
//启用 Spring 应用程序上下文的自动配置,尝试猜测和配置您可能需要的 bean。 自动配置类通常根据您的类路径和您定义的 bean 来应用。 
@EnableAutoConfiguration
//配置用于Configuration类的组件扫描指令。
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

	//这是一个方便的注解,相当于声明了@Configuration 、 @EnableAutoConfiguration 和 @ComponentScan 。
	//@SpringBootApplication注解将主配置类(即@SpringBootApplication标注的类)的所在包及子包里面所有组件扫描加载到Spring容器
	
	//省略属性
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

@EnableAutoConfiguration 注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
//使用AutoConfigurationPackages注册包。 当没有指定base packages或base package classes ,注解类的包被注册。
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
	
	//启用 Spring应用程序上下文的自动配置,尝试猜测和配置您可能需要的 bean。自动配置类通常根据您的类路径和您定义的 bean 来应用。

	//省略属性
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

AutoConfigurationImportSelector.java 类中的方法
该类的作用:去spring-boot-autoconfigure 目录下的路径里读取EnableAutoConfiguration 注解所在包及其子包下的需要实现自动加载装配的类,实例化后放入IOC容器中,这个过程也加载了常见的第三方组件的配置类。

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
		ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

	//省略其它部分代码

	//得到应该导入的类全限定名称的数组【重点】
	@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
		}
		//得到应该导入的自动配置
		AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
		//返回包含类名的数组
		//返回需要的类的全类名;是在 spring.factories 配置文件中的 @EnableAutoConfiguration 注解关联的xx自动配置类的全限定名称
		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);
	}
	
	//得到spring.factories配置中EnableAutoConfiguration 指定的值:即全部的候选自动装配的类的名称列表集合
	protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
		//框架内内部使用的通用工厂加载机制。
		//SpringFactoriesLoader从“META-INF/spring.factories”文件加载和实例化给定类型的工厂,这些文件可能存在于类路径中的多个 JAR 文件中。
		//loadFactoryNames():该方法使用给定的类加载器从"META-INF/spring.factories"加载 给定类型的工厂实现的完全限定类名。
		//spring.factories文件必须是Properties格式,其中 key 是接口或抽象类的完全限定名称,value 是逗号分隔的实现类名称列表。
		List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
				getBeanClassLoader());
		//Assert :帮助验证参数的断言实用程序类。
		//notEmpty(参数1,参数2) :参数1是要检查的集合;参数2是断言失败时使用的异常消息(也就是说如果集合为null或size=0,就抛出的异常消息)
		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;
	}

	//省略其它部分代码
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

加载并装配的目标文件 META-INF/spring.factories 的位置如下:
在这里插入图片描述
在这里插入图片描述

2.2、总结

  在Spring Boot的启动类中,有一个main方法运行了一个SpringApplication.run(SpringbootDemoApplication.class, args);方法,在run方法中必须要传入一个被@SpringBootApplication注解的类。
  随后解析@SpringBootApplication 注解,该注解启用了上下文bean的自动装配注解@EnableAutoConfiguration,随后解析该注解;该注解通过@Import注解引入了一个类AutoConfigurationImportSelector 类;该类的一个主要方法 selectImports() 该方法的作用是通过去spring-boot-autoconfigure 目录下的路径里读取EnableAutoConfiguration 注解所在包及其子包下的需要实现自动加载装配的类(xxxAutoConfiguration 可自动装配类)的全限定类名,然后通过反射创建所需自动装配的类,并在实例化后放入IOC容器中,这个过程也加载了常见的第三方组件的配置类。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/552765
推荐阅读
相关标签
  

闽ICP备14008679号