入口
通常一个简单的SpringBoot基础项目我们会有如下代码
@SpringBootApplication @RestController @RequestMapping("/") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 12345678910复制代码
值得关注的有SpringApplication.run以及注解@SpringBootApplication
run方法
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; } 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152复制代码
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 <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; } 123456789101112131415161718192021 createSpringFactoriesInstances 1 @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; } 1234567891011121314151617181920212223复制代码
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); } 1234567891011121314151617181920复制代码
最终输出内容类: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(); } } 1234567891011121314151617181920212223242526272829复制代码
希望通过本篇对于springboot启动方法的解读,让大家对springboot底层有了一个大致了解,只分析了主要方法,希望对大家有帮助
对于技术交流和探讨,或者想跳槽加薪的可以关注我的公众号,免费领取面试资料和技术书籍