栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot自动配置原理流程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot自动配置原理流程

前言

新公司太忙了,都没啥空更新博客,就随便记录一下以前的学习笔记吧。SpringBoot是基于Spring上的衍生框架,只要看懂了Spring的话,学这个就比较简单了;SpringBoot也是在当前微服务时代下流行的框架,并且该框架采用了自动配置,所以只要简单的配置一下就可以直接使用了,省去了很多做配置的时间,可以说是开箱即用。当前SpringBoot版本号为2.1.15.RELEASE版本

使用SpringBoot

这个可以借鉴一下官网:快速创建SpringBoot Initializer

我们新建一个maven项目,然后在pom.xml添加一下两种依赖中的一种即可


	org.springframework.boot
	spring-boot-starter-parent
	2.1.15.RELEASE



	
		
			org.springframework.boot
			spring-boot-dependencies
			2.1.15.RELEASE
			pom
			import
		
	

由于在SpringBoot框架中采用模块化形式,所以如果想要使用哪些模块,可直接引入spring-boot-starter-xxxx模块,例如:


	org.springframework.boot
	spring-boot-starter-test



	org.springframework.boot
	spring-boot-starter-web



	org.springframework.boot
	spring-boot-starter-jdbc



	org.springframework.boot
	spring-boot-starter-data-redis

引用好对应的模块之后,接下来就是打包了,一般采用SpringBoot自己封装的打包plugin工具,打成可执行包,如果要打成普通的引入jar包的话,那就不需要引入这个plugin了;


	
		
			org.springframework.boot
			spring-boot-maven-plugin
			
				
					
						repackage
					
				
			
		
	

然后就是启动了,在主类加上相应的配置,就可以使用了

@SpringBootApplication
public class App {
    public static void main( String[] args ) {
    	SpringApplication.run(App.class, args);
    }
}
启动原理

简单的使用讲过,接下来开始讲讲源码啦

@SpringBootApplication

注解主要作用是标识当前类为启动类,通过SpringBoot打包后的jar中找到该类,并启动当前应用,常用的属性有:

exclude:去除指定自动配置类。

scanbasePackages:扫描路径同ComponentScan一致

该注解源码中包含一下注解:

//设置为配置类相当于@Configuration,可自行点进去阅读
@SpringBootConfiguration
//自动配置注解,该注解包含@import注解
@EnableAutoConfiguration
//开启扫描路径,默认为启动类同路径下所有包
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
@EnableAutoConfiguration

该注解为表示自动配置,SpringBoot中自动配置,开箱即用的精髓都在于这个自动配置注解,该注解引用了@import注解,去扫描spring.factories文件下的

org.springframework.boot.autoconfigure.EnableAutoConfiguration

 对应的的自动配置类,并加载相关Bean注入到IOC容器当中

SpringApplication

该类是应用启动的主类,点进去看一下会发现其实就是创建SpringApplication对象并且调用run方法:

创建对象

读取累路径下meta-INF/spring.factories文件中的相关属性,并且拿到对应的Class对象

@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
	this.resourceLoader = resourceLoader;
	Assert.notNull(primarySources, "PrimarySources must not be null");
    //保存主配置类
	this.primarySources = new linkedHashSet<>(Arrays.asList(primarySources));
	this.webApplicationType = WebApplicationType.deduceFromClasspath();
    //读取spring.factories中ApplicationContextInitializer相关配置
	setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
    //读取spring.factories中ApplicationListener相关配置
	setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
	this.mainApplicationClass = deduceMainApplicationClass();
}

在SpringBoot默认的spring.factories文件中对应的ApplicationListener和ApplicationContextInitializer对应的示例:

# Run Listeners
org.springframework.boot.SpringApplicationRunListener=
org.springframework.boot.context.event.EventPublishingRunListener

# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,
org.springframework.boot.context.ContextIdApplicationContextInitializer,
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

# Application Listeners
org.springframework.context.ApplicationListener=
org.springframework.boot.ClearCachesApplicationListener,
org.springframework.boot.builder.ParentContextCloserApplicationListener,
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,
org.springframework.boot.context.FileEncodingApplicationListener,
org.springframework.boot.context.config.AnsiOutputApplicationListener,
org.springframework.boot.context.config.ConfigFileApplicationListener,
org.springframework.boot.context.config.DelegatingApplicationListener,
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,
org.springframework.boot.context.logging.LoggingApplicationListener,
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

拿到这些类,并执行对应的方法:

ApplicationContextInitializer

配置在meta-INF/spring.factories文件中,配置示例如上,继承接口并实现initialize方法,在Spring初始化之前执行该方法:

public class AppListenerStarter implements ApplicationContextInitializer {

	@Override
	public void initialize(ConfigurableApplicationContext applicationContext) {
		System.out.println("AppListenerStarter ... ");
		
	}

}
SpringApplicationRunListener

配置在meta-INF/spring.factories文件中,配置示例如上,继承接口并实现initialize方法,在Spring初始化之前执行该方法:

public class AppListener implements SpringApplicationRunListener {
    
    //必须要有参构造方法
	public AppListener(SpringApplication application, String[] args) {
		
	}
	
	@Override
	public void starting() {
		System.out.println("AppListener starting...");
	}

	@Override
	public void environmentPrepared(ConfigurableEnvironment environment) {
		Object o = environment.getSystemProperties().get("os.name");
		System.out.println("AppListener environmentPrepared..." + o);
	}

	@Override
	public void contextPrepared(ConfigurableApplicationContext context) {
		System.out.println("AppListener contextPrepared...");
	}

	@Override
	public void contextLoaded(ConfigurableApplicationContext context) {
		System.out.println("AppListener contextLoaded...");
	}

	@Override
	public void started(ConfigurableApplicationContext context) {
		System.out.println("AppListener ConfigurableApplicationContext started...");
	}

	@Override
	public void running(ConfigurableApplicationContext context) {
		System.out.println("AppListener running...");
	}

	@Override
	public void failed(ConfigurableApplicationContext context, Throwable exception) {
		System.out.println("AppListener failed...");
	}

}

执行结果为:

 调用run方法
//计时器,用来记录Spring容器启动花费的时间
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
//从spring.factories文件中获取SpringApplicationRunListener实现类
SpringApplicationRunListeners listeners = getRunListeners(args);
//开始执行对应的监听器
listeners.starting();
try {
	//封装命令行参数
	ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
	//封装监听器和参数
	ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
	configureIgnoreBeanInfo(environment);
	//打印Banner日志,就是那个SpringBoot的大LOGO
	Banner printedBanner = printBanner(environment);
	//创建指定SpringIOC容器
	context = createApplicationContext();
	//获取spring.factories文件中SpringBootExceptionReporter对应的Class,默认值为FailureAnalyzers
	exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
			new Class[] { ConfigurableApplicationContext.class }, context);
	//执行监听器中的contextPrepared()方法
	prepareContext(context, environment, listeners, applicationArguments, printedBanner);
	//刷新IOC容器,即调用Spring中的refresh方法(扫描,加载),优先加载业务组件中的,然后在加载spring.factories文件中自动配置的类
	refreshContext(context);
	afterRefresh(context, applicationArguments);
	//计时停止
	stopWatch.stop();
	if (this.logStartupInfo) {
		new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
	}
	//开始调用监听器中的started方法
	listeners.started(context);
	//回调ApplicationRunner和CommandLineRunner接口的实现类方法
	callRunners(context, applicationArguments);
}
catch (Throwable ex) {
	handleRunFailure(context, ex, exceptionReporters, listeners);
	throw new IllegalStateException(ex);
}

try {
	//调用监听器running方法
	listeners.running(context);
}
catch (Throwable ex) {
	handleRunFailure(context, ex, exceptionReporters, null);
	throw new IllegalStateException(ex);
}
return context;

至此,SpringBoot启动流程结束了,自动配置就是将spring.factories文件中的指定配置类全部加载到容器中,优先加载业务Bean,后加载自动配置类中的Bean。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/361827.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号