服务器之家

服务器之家 > 正文

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

时间:2021-08-29 12:51     来源/作者:码上代码

入口

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

?
1
2
3
4
5
6
7
8
9
10
@SpringBootApplication
@RestController
@RequestMapping("/")
public class Application {
 
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
 
}

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

run方法

?
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
public ConfigurableApplicationContext run(String... args) {
     // 秒表
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> 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

获取监听器

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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 <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
        ClassLoader classLoader = getClassLoader();
        // Use names and ensure unique to protect against duplicates
        // 读取 spring.factories
        Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
        // 创建SpringFactory实例
        List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
        /**
         * 排序 {@link Ordered}
         */
        AnnotationAwareOrderComparator.sort(instances);
        return instances;
    }
?
1
createSpringFactoriesInstances
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@SuppressWarnings("unchecked")
private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes,
       ClassLoader classLoader, Object[] args, Set<String> names) {
// 初始化
   List<T> instances = new ArrayList<>(names.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) {
           throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);
       }
   }
   return instances;
}

printBanner

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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

?
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
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底层有了一个大致了解,只分析了主要方法,希望对大家有帮助

到此这篇关于SpringBoot 启动方法run()源码赏析的文章就介绍到这了,更多相关SpringBoot 启动run()内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_44302240/article/details/110499108

标签:

相关文章

热门资讯

yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
2021年耽改剧名单 2021要播出的59部耽改剧列表
2021年耽改剧名单 2021要播出的59部耽改剧列表 2021-03-05
返回顶部