SpringBoot原理

什么是Spring Boot

Spring Boot基本介绍

这里我直接引用官网的描述,
官网地址:http://spring.io/projects/spring-boot

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”.

We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need very little Spring configuration.

Spring Boot 的特性

  • Create stand-alone Spring applications

  • Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)

  • Provide opinionated ‘starter’ dependencies to simplify your build configuration

  • Automatically configure Spring and 3rd party libraries whenever possible

  • Provide production-ready features such as metrics, health checks and externalized configuration

  • Absolutely no code generation and no requirement for XML configuration

Spring Boot启动原理

自动配置加载原理

这里咱们从SpringBoot的启动类开始,通过看SpringBoot的源码来逐步理解SpringBoot如何进行自动化配置

  • 我这里使用的SpringBoot版本为2.0.0.RELEASE

SpringBoot启动类如下

@SpringBootApplication
public class BookshopApplication {

	public static void main(String[] args) {
		SpringApplication.run(BookshopApplication.class, args);
	}
}

@SpringBootApplicaion是SpringBoot提供的一个注解,用于标志当前类是SpringBoot的启动类.那咱们从这个注解开始分析

@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 {
    
}

@Target、@Retention、@Documented、@Inherited这四个都是jdk自带的注解,给子含义如下

@Target:定义注解的作用目标

  • ElementType.TYPE:注解作用于接口、类、枚举、注解
  • ElementType.FIELD:注解作用于字段、枚举的常量
  • ElementType.METHOD:注解作用于方法
  • ElementType.PARAMETER:注解作用于方法参数
  • ElementType.CONSTRUCTOR:注解作用于构造函数
  • ElementType.LOCAL_VARIABLE:注解作用于局部变量
  • ElementType.ANNOTATION_TYPE:注解作用于注解
  • ElementType.PACKAGE:注解作用于包

@Retention:定义注解的保留策略
  • RetentionPolicy.SOURCE:注解仅存在于源码中,在class字节码文件中不包含
  • RetentionPolicy.CLASS:默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
  • RetentionPolicy.RUNTIME:注解会在class字节码文件中存在,在运行时可以通过反射获取到

@Documented:制作javadoc时,是否将注解信息加入文档
@Inherited:子类可以继承父类中的该注解

@SpringBootConfiguration是SpringBoot中的注解,咱们看看它的源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {

}

@Configuration为Spring框架提供的注解,标注这个类是一个配置类



这里我们先来看@AutoConfigurationPackage,后面我们再来看导入的AutoConfigurationImportSelector类

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    
}

我们先来看@AutoConfigurationPackage

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {

}

显而易见的是AutoConfigurationPackages中的Registrar类是此注解的关键,进去看看源码(这里我列出一些关键性的代码)
在这里插入图片描述
接下来我们去看register()方法
在这里插入图片描述

经过上面这个流程就把SpringBoot启动类所在的包下的所有java类都加载到Spring框架中了;也就是说SpringBoot只能管理启动类所在的包内的java类


下面我们回过头来看@EnableAutoConfiguration中的导入的AutoConfigurationImportSelector类,关键方法如下

@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
		}
		try {
			AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
					.loadMetadata(this.beanClassLoader);
			AnnotationAttributes attributes = getAttributes(annotationMetadata);
			List<String> configurations = getCandidateConfigurations(annotationMetadata,
					attributes);
			configurations = removeDuplicates(configurations);
			configurations = sort(configurations, autoConfigurationMetadata);
			Set<String> exclusions = getExclusions(annotationMetadata, attributes);
			checkExcludedClasses(configurations, exclusions);
			configurations.removeAll(exclusions);
			configurations = filter(configurations, autoConfigurationMetadata);
			fireAutoConfigurationImportEvents(configurations, exclusions);
			return StringUtils.toStringArray(configurations);
		}
		catch (IOException ex) {
			throw new IllegalStateException(ex);
		}
	}

其中最关键的是AutoConfigurationMetadataLoader.loadMetadata()方法,下面来分析此方法主要干了什么
在这里插入图片描述

那么META-INF/spring-autoconfigure-metadata.properties中道理配置了什么东西呢?我们可以在spring-boot-autoconfigure包中找到此配置文件,文件内容如下
在这里插入图片描述

可以看到,配置文件中有非常多的AutoConfiguration,那么这些Configuration是用来干嘛的呢?且看下回分解

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值