美文网首页
spring-boot源码解析-启动及自动配置篇

spring-boot源码解析-启动及自动配置篇

作者: 喝不醉的Solace | 来源:发表于2018-08-13 15:07 被阅读0次

首先放一张接口设计图:

spring-boot 启动分析

SpringApplication.run(BlogApplication.class, args);

\1/

跟踪到

private void initialize(Object[] sources) {

    if(sources != null && sources.length > 0) {

        this.sources.addAll(Arrays.asList(sources));

    }

    this.webEnvironment = this.deduceWebEnvironment();

//加载所有jar中spring-factories下的所有工厂

    this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));

    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));

    this.mainApplicationClass = this.deduceMainApplicationClass();

}

public static List loadFactoryNames(Class factoryClass, ClassLoader classLoader) {

    String factoryClassName = factoryClass.getName();

    try {

        Enumeration urls = classLoader != null?classLoader.getResources("META-INF/spring.factories"):ClassLoader.getSystemResources("META-INF/spring.factories");

        ArrayList result = new ArrayList();

        while(urls.hasMoreElements()) {

            URL url = (URL)urls.nextElement();

            Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));

            String factoryClassNames = properties.getProperty(factoryClassName);//加载所有工厂

            result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));

        }

        return result;

    } catch (IOException var8) {

        throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() + "] factories from location [" + "META-INF/spring.factories" + "]", var8);

    }

}

这些工厂对应实现了不同的工厂类

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

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

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

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

    AnnotationAwareOrderComparator.sort(instances);

    return instances;

}

* e.g 需要实例化的工厂

实例化所有工厂并排序

private void initialize(Object[] sources) {

    if(sources != null && sources.length > 0) {

        this.sources.addAll(Arrays.asList(sources));

    }

    this.webEnvironment = this.deduceWebEnvironment();

    this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));

    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));

    this.mainApplicationClass = this.deduceMainApplicationClass();

}

接下来为每个工厂设置监听

private Class deduceMainApplicationClass() {

    try {

        StackTraceElement[] stackTrace = (new RuntimeException()).getStackTrace();

        StackTraceElement[] var2 = stackTrace;

        int var3 = stackTrace.length;

        for(int var4 = 0; var4 < var3; ++var4) {

            StackTraceElement stackTraceElement = var2[var4];

            if("main".equals(stackTraceElement.getMethodName())) {

                return Class.forName(stackTraceElement.getClassName());

            }

        }

    } catch (ClassNotFoundException var6) {

        ;

    }

    return null;

}

设置异常处理栈

SpringApplication设置并初始化完毕,接下来看下它的run方法

public ConfigurableApplicationContext run(String... args) {

    StopWatch stopWatch = new StopWatch();

    stopWatch.start();

    ConfigurableApplicationContext context = null;

    FailureAnalyzers analyzers = null;

    this.configureHeadlessProperty();

    SpringApplicationRunListeners listeners = this.getRunListeners(args);//加载刚才所有 //SpringApplicationRunListener listener实例并启动

    listeners.starting();

    try {

        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);

        ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);

        Banner printedBanner = this.printBanner(environment);

        context = this.createApplicationContext();

        new FailureAnalyzers(context);

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

        this.refreshContext(context);

        this.afterRefresh(context, applicationArguments);

        listeners.finished(context, (Throwable)null);

        stopWatch.stop();

        if(this.logStartupInfo) {

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

        }

        return context;

    } catch (Throwable var9) {

        this.handleRunFailure(context, listeners, (FailureAnalyzers)analyzers, var9);

        throw new IllegalStateException(var9);

    }

}

看下listener.start方法在干什么:

依次执行以上构造方法

public void starting() {

    this.initialMulticaster.multicastEvent(new ApplicationStartedEvent(this.application, this.args));

}

public void multicastEvent(ApplicationEvent event) {

    this.multicastEvent(event, this.resolveDefaultEventType(event));

}

遍历所有观察者,发布事件

public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {

    ResolvableType type = eventType != null?eventType:this.resolveDefaultEventType(event);

    Iterator var4 = this.getApplicationListeners(event, type).iterator();

    while(var4.hasNext()) {

        final ApplicationListener listener = (ApplicationListener)var4.next();

        Executor executor = this.getTaskExecutor();

        if(executor != null) {

            executor.execute(new Runnable() {

                public void run() {

                    SimpleApplicationEventMulticaster.this.invokeListener(listener, event);

                }

            });

        } else {

            this.invokeListener(listener, event);

        }

    }

}

//发布事件,spring启动啦,各部门该干啥干啥去啦

protected void invokeListener(ApplicationListener listener, ApplicationEvent event) {

    ErrorHandler errorHandler = this.getErrorHandler();

    if(errorHandler != null) {

        try {

            listener.onApplicationEvent(event);

        } catch (Throwable var7) {

            errorHandler.handleError(var7);

        }

    } else {

        try {

            listener.onApplicationEvent(event);

        } catch (ClassCastException var8) {

            String msg = var8.getMessage();

            if(msg != null && !msg.startsWith(event.getClass().getName())) {

                throw var8;

            }

            Log logger = LogFactory.getLog(this.getClass());

            if(logger.isDebugEnabled()) {

                logger.debug("Non-matching event type for listener: " + listener, var8);

            }

        }

    }

}

//接着发布spring准备好了启动事件

ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);

//打印logo,初始化各个上下文

context = this.createApplicationContext();

new FailureAnalyzers(context);

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

this.refreshContext(context);

this.afterRefresh(context, applicationArguments);

listeners.finished(context, (Throwable)null);

stopWatch.stop();

//stopWatch监听启动用时

相关文章

网友评论

      本文标题:spring-boot源码解析-启动及自动配置篇

      本文链接:https://www.haomeiwen.com/subject/ijkubftx.html