SpringBoot源码解析(1.3)-自动装配原理(2)

SpringBoot源码解析(1.3)-自动装配原理(2)

承接上文:https://blog.csdn.net/sql2008help/article/details/123253292

上篇文章中主要解析了 SpringApplication 的初始化过程,其中重要的一点是读取 META-INF/spring.factories 配置并缓存至 SpringFactoriesLoader.cache ,cache类型为 Map> ,之后初始化 springFactories (对应 getSpringFactoriesInstances 方法)从cache中读取配置后实例化即可

以下 run 方法为SpringApplication 的实例方法:

public ConfigurableApplicationContext run(String... args) {
        long startTime = System.nanoTime();
        //创建引导程序上下文
        DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
        ConfigurableApplicationContext context = null;
        this.configureHeadlessProperty();
        // 实例化 runListeners 当前spring.factories中只配置了 
        // org.springframework.boot.context.event.EventPublishingRunListener
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting(bootstrapContext, this.mainApplicationClass);

        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            Banner printedBanner = this.printBanner(environment);
            // 创建 ConfigurableApplicationContext 应用上下文
            context = this.createApplicationContext();
            context.setApplicationStartup(this.applicationStartup);
            this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
            this.refreshContext(context);
            this.afterRefresh(context, applicationArguments);
            Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), timeTakenToStartup);
            }

            listeners.started(context, timeTakenToStartup);
            this.callRunners(context, applicationArguments);
        } catch (Throwable var12) {
            this.handleRunFailure(context, var12, listeners);
            throw new IllegalStateException(var12);
        }

        try {
            Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
            listeners.ready(context, timeTakenToReady);
            return context;
        } catch (Throwable var11) {
            this.handleRunFailure(context, var11, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var11);
        }
    }

this.getRunListeners(args) 方法:

private SpringApplicationRunListeners getRunListeners(String[] args) {
    Class[] types = new Class[]{SpringApplication.class, String[].class};
    return new SpringApplicationRunListeners(logger, this.getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args), this.applicationStartup);
}

META-INF/spring.factories 中 SpringApplicationRunListener key对应的value值为EventPublishingRunListener:

# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener

以上 this.getSpringFactoriesInstances 方法返回值为 EventPublishingRunListener 实例构成的集合

private  Collection getSpringFactoriesInstances(Class type, Class[] parameterTypes, Object... args) {
   ClassLoader classLoader = this.getClassLoader();
    Set names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
    List instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
    AnnotationAwareOrderComparator.sort(instances);
    return instances;
}

SpringApplicationRunListeners

class SpringApplicationRunListeners {
    private final Log log;
    private final List listeners;
    private final ApplicationStartup applicationStartup;

    SpringApplicationRunListeners(Log log, Collection listeners, ApplicationStartup applicationStartup) {
        this.log = log;
        this.listeners = new ArrayList(listeners);
        this.applicationStartup = applicationStartup;
    }
}

listeners.starting(bootstrapContext, this.mainApplicationClass); 方法:
依次执行 ApplicationListener(即 SpringApplication listeners ) onApplicationEvent 方法

this.createApplicationContext() 方法:
创建应用上下文:AnnotationConfigServletWebApplicationContext,具体可看:https://blog.csdn.net/sql2008help/article/details/123314453

this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner) 方法:

private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
        context.setEnvironment(environment);
        this.postProcessApplicationContext(context);
        //执行 SpringApplication 初始化器initialize方法
        this.applyInitializers(context);
        listeners.contextPrepared(context);
        bootstrapContext.close(context);
        if (this.logStartupInfo) {
            this.logStartupInfo(context.getParent() == null);
            this.logStartupProfileInfo(context);
        }

        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
        if (printedBanner != null) {
            beanFactory.registerSingleton("springBootBanner", printedBanner);
        }

        if (beanFactory instanceof AbstractAutowireCapableBeanFactory) {
            ((AbstractAutowireCapableBeanFactory)beanFactory).setAllowCircularReferences(this.allowCircularReferences);
            if (beanFactory instanceof DefaultListableBeanFactory) {
                ((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
            }
        }

        if (this.lazyInitialization) {
            context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
        }

        Set sources = this.getAllSources();
        Assert.notEmpty(sources, "Sources must not be empty");
        this.load(context, sources.toArray(new Object[0]));
        listeners.contextLoaded(context);
    }
 
  

SpringApplication applyInitializers 方法:

如下代码获取 SpringApplication List> initializers 并循环执行 ApplicationContextInitializer initialize 方法

protected void applyInitializers(ConfigurableApplicationContext context) {
    Iterator var2 = this.getInitializers().iterator();

    while(var2.hasNext()) {
        ApplicationContextInitializer initializer = (ApplicationContextInitializer)var2.next();
        Class requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(), ApplicationContextInitializer.class);
        Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
        initializer.initialize(context);
    }
}

执行完 applyInitializers 方法后,AnnotationConfigServletWebApplicationContext context beanFactoryPostProcessors 属性值有所改变,如下:

listeners.contextPrepared(context) 方法:

即调用 SpringApplicationRunListeners contextPrepared 方法,调用顺序如下:

void contextPrepared(ConfigurableApplicationContext context) {
   this.doWithListeners("spring.boot.application.context-prepared", (listener) -> {
        // 如下  this.listeners.forEach(listenerAction); 最终会调用此方法,
        // 当前只有EventPublishingRunListener实现了SpringApplicationRunListener接口
        listener.contextPrepared(context);
    });
}

private void doWithListeners(String stepName, Consumer listenerAction) {
    this.doWithListeners(stepName, listenerAction, (Consumer)null);
}

private void doWithListeners(String stepName, Consumer listenerAction, Consumer stepAction) {
    StartupStep step = this.applicationStartup.start(stepName);
    this.listeners.forEach(listenerAction);
    if (stepAction != null) {
        stepAction.accept(step);
    }

    step.end();
}
package org.springframework.boot.context.event;

public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
    private final SpringApplication application;
    private final String[] args;
    private final SimpleApplicationEventMulticaster initialMulticaster;

    public EventPublishingRunListener(SpringApplication application, String[] args) {
        this.application = application;
        this.args = args;
        this.initialMulticaster = new SimpleApplicationEventMulticaster();
        Iterator var3 = application.getListeners().iterator();

        while(var3.hasNext()) {
            ApplicationListener listener = (ApplicationListener)var3.next();
            this.initialMulticaster.addApplicationListener(listener);
        }

    }
    
    public void starting(ConfigurableBootstrapContext bootstrapContext) {
        this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(bootstrapContext, this.application, this.args));
    }

    public void contextPrepared(ConfigurableApplicationContext context) {
        this.initialMulticaster.multicastEvent(new ApplicationContextInitializedEvent(this.application, this.args, context));
    }
}

this.load(context, sources.toArray(new Object[0])) 方法:

protected void load(ApplicationContext context, Object[] sources) {
  if (logger.isDebugEnabled()) {
       logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
   }
   // 创建读取bean定义的导入类实例
   BeanDefinitionLoader loader = this.createBeanDefinitionLoader(this.getBeanDefinitionRegistry(context), sources);
   
   。。。。省略。。。。

   // 重点看这个方法
   loader.load();
}

load 方法执行完后,beanFactory 中 bean定义 beanDefinitionMap 如下:
SpringBoot源码解析(1.3)-自动装配原理(2)_第1张图片
具体查看:https://blog.csdn.net/sql2008help/article/details/123346522

this.refreshContext(context) 方法:

具体查看:
https://blog.csdn.net/sql2008help/article/details/123354118

你可能感兴趣的:(SpringBoot,spring,boot,java,spring)