SpringBoot之旅-启动原理及自定义starter
JAVA烂猪皮
共 12356字,需浏览 25分钟
· 2023-08-01
public static ConfigurableApplicationContext run(Class<?>[] primarySources,
String[] args) {
return new SpringApplication(primarySources).run(args);
}
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
//保存主配置类
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
//确定web应用类型
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer;然后保存起来
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
//从类路径下找到ETA-INF/spring.factories配置的所有ApplicationListener
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
//从多个配置类中找到有main方法的主配置类
this.main
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
//从类路径下META-INF/spring.factories获取SpringApplicationRunListeners
SpringApplicationRunListeners listeners = getRunListeners(args);
//回调所有的获取SpringApplicationRunListener.starting()方法
listeners.starting();
try {
//封装命令行参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
//准备环境
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);//创建环境完成后回调SpringApplicationRunListener.environmentPrepared();表示环境准备完成
configureIgnoreBeanInfo(environment);
//打印Banner图
Banner printedBanner = printBanner(environment);
//创建ApplicationContext,决定创建web的ioc还是普通的ioc
context = createApplicationContext();
//异常分析报告
exceptionReporters = getSpringFactoriesInstances(
SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
//准备上下文环境,将environment保存到ioc中
//applyInitializers():回调之前保存的所有的ApplicationContextInitializer的initialize方法
//listeners.contextPrepared(context)
//prepareContext运行完成以后回调所有的SpringApplicationRunListener的contextLoaded()
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
//刷新容器,ioc容器初始化(如果是web应用还会创建嵌入式的Tomcat)
//扫描,创建,加载所有组件的地方,(配置类,组件,自动配置)
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
//所有的SpringApplicationRunListener回调started方法
listeners.started(context);
//从ioc容器中获取所有的ApplicationRunner和CommandLineRunner进行回调,
//ApplicationRunner先回调,CommandLineRunner再回调
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
//所有的SpringApplicationRunListener回调running方法
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
//整个SpringBoot应用启动完成以后返回启动的ioc容器
return context;
}
<dependencies>
<!--引入自动配置模块-->
<dependency>
<groupId>com.yuanqinnan-starter</groupId>
<artifactId>yuanqinnan-springboot-starter-autoconfigurer</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.yuanqinnan-starter</groupId>
<artifactId>yuanqinnan-springboot-starter-autoconfigurer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--引入spring-boot-starter;所有starter的基本配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
@ConfigurationProperties(prefix = "yuanqinnan.hello")
public class HelloProperties {
//前缀
private String prefix;
//后缀
private String suffix;
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
}
public class HelloService {
HelloProperties helloProperties;
public HelloProperties getHelloProperties() {
return helloProperties;
}
public void setHelloProperties(HelloProperties helloProperties) {
this.helloProperties = helloProperties;
}
public String sayHello(String name) {
return helloProperties.getPrefix() + "-" + name + helloProperties.getSuffix();
}
}
@Configuration
@ConditionalOnWebApplication //web应用才生效
@EnableConfigurationProperties(HelloProperties.class)
public class HelloServiceAutoConfiguration {
@Autowired
HelloProperties helloProperties;
@Bean
public HelloService helloService(){
HelloService service = new HelloService();
service.setHelloProperties(helloProperties);
return service;
}
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.yuanqinnan.starter.HelloServiceAutoConfiguration
<!--引入自定义starter-->
<dependency>
<groupId>com.yuanqinnan.starter</groupId>
<artifactId>yuanqinnan-springboot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
yuanqinnan.hello.prefix=早安
yuanqinnan.hello.suffix=晚安
@Autowired
HelloService helloService;
@Test
public void contextLoads() {
System.out.println(helloService.sayHello("世界"));
}
剩下的就不会给大家一展出来了,以上资料按照一下操作即可获得
——将文章进行转发和评论,关注公众号【Java烤猪皮】,关注后继续后台回复领取口令“ 666 ”即可免费领文章取中所提供的资料。
腾讯、阿里、滴滴后台试题汇集总结 — (含答案)
面试:史上最全多线程序面试题!
最新阿里内推Java后端试题
JVM难学?那是因为你没有真正看完整这篇文章
关注作者微信公众号 — 《JAVA烤猪皮》
了解了更多java后端架构知识以及最新面试宝典
看完本文记得给作者点赞+在看哦~~~大家的支持,是作者来源不断出文的动力~
评论
SpringBoot 实现图片防盗链功能
程序员的成长之路互联网/程序员/技术/资料共享 关注阅读本文大概需要 4 分钟。来自:blog.csdn.net/weixin_46157208/article/details/138051737前言出于安全考虑,我们需要后端返回的图片只允许在某个网站内展示,不想被爬虫拿到图片地
程序员的成长之路
0
springboot第70集:字节跳动后端三面经,一文让你走出微服务迷雾架构周刊
创建一个使用Kubernetes (K8s) 和 Jenkins 来自动化 GitLab 前端项目打包的CI/CD流水线,需要配置多个组件。下面,我将概述一个基本的设置步骤和示例脚本,以帮助你理解如何使用这些工具整合一个自动化流程。前提条件确保你已经有:Kubernetes 集群:用于部署 Jenk
程序源代码
0
乐普心安宝及心电图机,助力安康市搭建“心电一张网”,打通全域“生命线”!
为持续推动胸痛中心建设,助力全民健康,全面提升心血管疾病等急危重症救治能力水平。4月20日,由安康市卫健委主办、安康市中医医院承办的“第七届心血管汉江学术会议暨安康市胸痛中心大会”在高新国际会议中心顺利举行。市人大常委会主任王彪、市政协副主席唐纹、市政府党组成员刘英华等领导亲临现场,受邀参会的中国科
乐普医疗AI
0
每天骑的共享单车是什么通信原理,有人了解过吗?
转自:网络我们经常骑的共享单车到底是什么通信原理,有人了解过吗?现在就带大家了解下。一、智能车锁共享单车最核心的硬件是智能车锁,主要用于实现控制和定位功能。车锁内集成了嵌入式芯片(通信模块),GPS模块和物联网SIM卡。智能锁制造商通过在锁内集成带有独立号码的SIM卡,通过2G、3G、4G网络,与云
菜鸟学Python
1
面试官:谈谈前端路由的实现原理【hash&history】
哈喽,大家好我是考拉🐨。今天我们来聊一聊前端路由。当谈到前端路由时,指的是在前端应用中管理页面导航和URL的机制。前端路由使得单页应用(Single-Page Application,SPA)能够在用户与应用交互时动态地加载不同的视图,而无需每次都重新加载整个页面。在前端开发中,常用的前端路由库有很
程序员成长指北
10
性能爆表:SpringBoot利用ThreadPoolTaskExecutor批量插入百万级数据实测!
关注我们,设为星标,每天7:40不见不散,架构路上与您共享回复架构师获取资源大家好,我是你们的朋友架构君,一个会写代码吟诗的架构师。来源:azdebug.blog.csdn.net/article/details/103697108前言具体实现细节测试结果总结前言开发目的: 提高百万级数据
Java架构师社区
0
无任务学习及在机器人任务和运动规划中的应用
大数据文摘授权转载自中国人工智能学会作者:张宪琦,范晓鹏摘 要:本文提出了无任务学习的方法,阐述了其与现有方法(包括自监督学习、迁移学习、模仿学习、强化学习)的区别与联系;然后,介绍了无任务学习在机器人任务和运动规划领域的应用,并分析了无任务学习在该领域的优势和主要研究难点。最后,对无任务学习在机器
大数据文摘
0
Nat. Commun. | gLM:基于宏基因组预训练语言模型的基因和蛋白调控及功能预测算法
2024年4月3日,Peter R. Girguis、Sergey Ovchinnikov、Yunha Hwang、Andre L. Cornman和Elizabeth H. Kellogg几人在Nature Communications上发表了一篇题为“Genomic language model
生信宝典
0