SpringBoot 启动方法run()源码解析

网友投稿 224 2023-01-24

SpringBoot 启动方法run()源码解析

入口

通常一个简单的SpringBoot基础项目我们会有如下代码

@SpringBootApplication

@RestController

@RequestMapping("/")

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}

值得关注的有SpringApplication.run以及注解@SpringBootApplication

run方法

public ConfigurableApplicationContext run(String... args) {

// 秒表

StopWatch stopWatch = new StopWatch();

stopWatch.start();

ConfigurableApplicationContext context = null;

Collection exceptionReporters = new ArrayList<>();

configureHeadlessProperty();

// 获取监听器

SpringApplicationRunListeners listeners = getRunListeners(args);

// 监听器启动

listeners.starting();

try {

// application 启动参数列表

ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);

ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);

// 配置忽略的bean信息

configureIgnoreBeanInfo(environment);

Banner printedBanner = printBanner(environment);

// 创建应用上下文

context = createApplicationContext();

exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,

new Class[] { ConfigurableApplicationContext.class }, context);

// 准备上下文,装配bean

prepareContext(context, environment, listeners, applicationArguments, printedBanner);

// 上下文刷新

refreshContext(context);

// 刷新后做什么

afterRefresh(context, applicationArguments);

stopWatch.stop();

if (this.logStartupInfo) {

new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);

}

// 监听器开始了

listeners.started(context);

// 唤醒

callRunners(context, applicationArguments);

}

catch (Throwable ex) {

handleRunFailure(context, ex, exceptionReporters, listeners);

throw new IllegalStateException(ex);

}

try {

// 监听器正式运行

listeners.running(context);

}

catch (Throwable ex) {

handleRunFailure(context, ex, exceptionReporters, null);

throw new IllegalStateException(ex);

}

return context;

}

getRunListeners

获取监听器

private SpringApplicationRunListeners getRunListeners(String[] args) {

Class>[] types = new Class>[] { SpringApplication.class, String[].class };

// 获取 Spring Factory 实例对象

return new SpringApplicationRunListeners(logger,

getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));

}

private Collection getSpringFactoriesInstances(Class type, Class>[] parameterTypes, Object... args) {

ClassLoader classLoader = getClassLoader();

// Use names and ensure unique to protect against duplicates

// 读取 spring.factories

Set names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));

// 创建SpringFactory实例

List instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);

/**

* 排序 {@link Ordered}

*/

AnnotationAwareOrderComparator.sort(instances);

return instances;

}

createSpringFactoriesInstances

@SuppressWarnings("unchecked")

private List createSpringFactoriesInstances(Class type, Class>[] parameterTypes,

ClassLoader classLoader, Object[] args, Set names) {

// 初始化

List instances = new ArrayList<>(namvpUWPzkTes.size());

for (String name : names) {

try {

// 通过名字创建类的class对象

Class> instanceClass = ClassUtils.forName(name, classLoader);

Assert.isAssignable(type, instanceClass);

// 构造器获取

Constructor> constructor = instanceClass.getDeclaredConstructor(parameterTypes);

// 创建具体实例

T instance = (T) BeanUtils.instantiateClass(constructor, args);

// 加入实例表中

instances.add(instance);

}

catch (Throwable ex) {

throwhttp:// new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);

}

}

return instances;

}

printBanner

private Banner printBanner(ConfigurableEnvironment environment) {

if (this.bannerMode == Banner.Mode.OFF) {

return null;

}

ResourceLoader resourceLoader = (this.resourceLoader != null) ? this.resourceLoader

: new DefaultResourceLoader(getClassLoader());

// 创建打印器

SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(resourceLoader, this.banner);

if (this.bannerMode == Mode.LOG) {

// 输出

return bannerPrinter.print(environment, this.mainApplicationClass, logger);

}

// 输出

return bannerPrinter.print(environment, this.mainApplicationClass, System.out);

}

Banner print(Environment environment, Class> sourceClass, PrintStream out) {

Banner banner = getBanner(environment);

banner.printBanner(environment, sourceClass, out);

return new PrintedBanner(banner, sourceClass);

}

最终输出内容类:org.springframework.boot.SpringBootBanner

class SpringBootBanner implements Banner {

private static final String[] BANNER = { "", " . ____ _ __ _ _",

" /\\\\ / ___'_ __ _ _(_)_ __ __ _ \\ \\ \\ \\", "( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\",

" \\\\/ ___)| |_)| | | | | || (_| | ) ) ) )", " ' |____| .__|_| |_|_| |_\\__, | / / / /",

" =========|_|==============|___/=/_/_/_/" };

private static final String SPRING_BOOT = " :: Spring Boot :: ";

private static final int STRAP_LINE_SIZE = 42;

@Override

public void printBanner(Environment environment, Class> sourceClass, PrintStream printStream) {

for (String line : BANNER) {

printStream.println(line);

}

String version = SpringBootVersion.getVersion();

version = (version != null) ? " (v" + version + ")" : "";

StringBuilder padding = new StringBuilder();

while (padding.length() < STRAP_LINE_SIZE - (version.length() + SPRING_BOOT.length())) {

padding.append(" ");

}

printStream.println(AnsiOutput.toString(AnsiColor.GREEN, SPRING_BOOT, AnsiColor.DEFAULT, padding.toString(),

AnsiStyle.FAINT, version));

printStream.println();

}

}

希望通过本篇对于springboot启动方法的解读,让大家对springboot底层有了一个大致了解,只分析了主要方法,希望对大家有帮助

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:新浪股票接口api 交易(新浪股票接口api 交易平台)
下一篇:免费api接口调用大全(免费开放api接口)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~