springboot系列之启动流程

Springboot简介

springboot封装了Spring组件,基于约定优于配置。晋升了开发效率,本文次要解说springboot框架的启动过程。

启动流程剖析

1、首先,咱们看一下启动类SpringApplication,它是位于org.springframework.boot包上面的。我的项目启动类源码

@SpringBootApplicationpublic class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }}

这里用到了SpringBootApplication注解,而后在main办法中启动boot利用。

2、咱们接下来看看SpringBootApplication注解的源码

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })public @interface SpringBootApplication {    /**     * Exclude specific auto-configuration classes such that they will never be applied.     * @return the classes to exclude     */    @AliasFor(annotation = EnableAutoConfiguration.class)    Class<?>[] exclude() default {};    /**     * Exclude specific auto-configuration class names such that they will never be     * applied.     * @return the class names to exclude     * @since 1.3.0     */    @AliasFor(annotation = EnableAutoConfiguration.class)    String[] excludeName() default {};    /**     * Base packages to scan for annotated components. Use {@link #scanBasePackageClasses}     * for a type-safe alternative to String-based package names.     * @return base packages to scan     * @since 1.3.0     */    @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")    String[] scanBasePackages() default {};    /**     * Type-safe alternative to {@link #scanBasePackages} for specifying the packages to     * scan for annotated components. The package of each class specified will be scanned.     * <p>     * Consider creating a special no-op marker class or interface in each package that     * serves no purpose other than being referenced by this attribute.     * @return base packages to scan     * @since 1.3.0     */    @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")    Class<?>[] scanBasePackageClasses() default {};}

它是位于org.springframework.boot.autoconfigure包上面的。咱们能够看到它依赖了几个重要的注解SpringBootConfiguration、EnableAutoConfiguration、ComponentScan这三个注解。其中EnableAutoConfiguration就是springboot主动配置用到的类,在接下来咱们将会重点介绍。

3、咱们在看SpringApplication运行的run办法

    /**     * Static helper that can be used to run a {@link SpringApplication} from the     * specified sources using default settings and user supplied arguments.     * @param primarySources the primary sources to load     * @param args the application arguments (usually passed from a Java main method)     * @return the running {@link ApplicationContext}     */    public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {        return new SpringApplication(primarySources).run(args);    }

首先,创立SpringApplication利用对象,而后调用run办法传入启动参数

    public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {        this.resourceLoader = resourceLoader;        Assert.notNull(primarySources, "PrimarySources must not be null");        this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));        this.webApplicationType = WebApplicationType.deduceFromClasspath();        setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));        this.mainApplicationClass = deduceMainApplicationClass();    }
    this.webApplicationType = WebApplicationType.deduceFromClasspath();        setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));        this.mainApplicationClass = deduceMainApplicationClass();

这是创建对象的办法,先校验启动类,而后调用deduceFromClasspath办法推断一个利用类型(是否是web我的项目)初始化工厂类,设置Spring监听器(观察者模式)。

4、创立好对象后,咱们接着看run办法

/**     * Run the Spring application, creating and refreshing a new     * {@link ApplicationContext}.     * @param args the application arguments (usually passed from a Java main method)     * @return a running {@link ApplicationContext}     */    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 {            //通过启动参数构建利用参数            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);            //创立上线文环境            ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);            //配置疏忽的bean信息            configureIgnoreBeanInfo(environment);            //打印boot启动logo            Banner printedBanner = printBanner(environment);            //创立上线文(容器)            context = createApplicationContext();            //获取异样汇合            exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,                    new Class[] { ConfigurableApplicationContext.class }, context);            //筹备上下文            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;    }

咱们只看几个重要的办法,首先看createApplicationContext()创立上下文(容器)办法

    /**     * Strategy method used to create the {@link ApplicationContext}. By default this     * method will respect any explicitly set application context or application context     * class before falling back to a suitable default.     * @return the application context (not yet refreshed)     * @see #setApplicationContextClass(Class)     */    protected ConfigurableApplicationContext createApplicationContext() {        //获取启动类        Class<?> contextClass = this.applicationContextClass;        //推断上下文类型,默认web类型,        if (contextClass == null) {            try {                switch (this.webApplicationType) {                case SERVLET:                    contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);                    break;                //flux类型上下文                case REACTIVE:                    contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);                    break;                default:                    contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);                }            }            catch (ClassNotFoundException ex) {                throw new IllegalStateException(                        "Unable create a default ApplicationContext, " + "please specify an ApplicationContextClass",                        ex);            }        }        //实例化上下文,容器        return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);    }

咱们在看,prepareContext(context, environment, listeners, applicationArguments, printedBanner);筹备上下文办法

    private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,            SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {        //设置上下文环境                context.setEnvironment(environment);        //解决利用上下文        postProcessApplicationContext(context);        //利用初始化类        applyInitializers(context);        //监听器筹备上下文        listeners.contextPrepared(context);        if (this.logStartupInfo) {            logStartupInfo(context.getParent() == null);            logStartupProfileInfo(context);        }        // Add boot specific singleton beans        //创立bean工厂        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();        //注册利用参数bean                                beanFactory.registerSingleton("springApplicationArguments", applicationArguments);        if (printedBanner != null) {            beanFactory.registerSingleton("springBootBanner", printedBanner);        }        if (beanFactory instanceof DefaultListableBeanFactory) {            ((DefaultListableBeanFactory) beanFactory)                    .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);        }        // Load the sources        Set<Object> sources = getAllSources();        Assert.notEmpty(sources, "Sources must not be empty");        load(context, sources.toArray(new Object[0]));        listeners.contextLoaded(context);    }

在看、重要的refreshContext(context);刷新上下文办法重点

    private void refreshContext(ConfigurableApplicationContext context) {        refresh(context);        if (this.registerShutdownHook) {            try {                context.registerShutdownHook();            }            catch (AccessControlException ex) {                // Not allowed in some environments.            }        }    }

点进去refresh(context);办法进入

    /**     * Refresh the underlying {@link ApplicationContext}.     * @param applicationContext the application context to refresh     */    protected void refresh(ApplicationContext applicationContext) {        Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);        ((AbstractApplicationContext) applicationContext).refresh();    }

类型转换为AbstractApplicationContext,持续看refresh办法

@Override    public void refresh() throws BeansException, IllegalStateException {        synchronized (this.startupShutdownMonitor) {            //筹备刷新            prepareRefresh();            // 刷新子类工厂            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();            // 筹备beanFactory            prepareBeanFactory(beanFactory);            try {                // 解决bean工厂                postProcessBeanFactory(beanFactory);                // 调用bean共产处理器重点            invokeBeanFactoryPostProcessors(beanFactory);                // 注册bean工厂处理器            registerBeanPostProcessors(beanFactory);                // 初始化音讯类                initMessageSource();                // 初始化利用事件播送                initApplicationEventMulticaster();                // 正在刷新的                onRefresh();                // 公布事件监听器                registerListeners();                // 实现bean工厂注册            finishBeanFactoryInitialization(beanFactory);                // 实现事件刷新                finishRefresh();            }            catch (BeansException ex) {                if (logger.isWarnEnabled()) {                    logger.warn("Exception encountered during context initialization - " +                            "cancelling refresh attempt: " + ex);                }                // Destroy already created singletons to avoid dangling resources.                destroyBeans();                // Reset 'active' flag.                cancelRefresh(ex);                // Propagate exception to caller.                throw ex;            }            finally {                // Reset common introspection caches in Spring's core, since we                // might not ever need metadata for singleton beans anymore...                resetCommonCaches();            }        }    }

咱们在看prepareRefresh筹备刷新办法

/**     * Prepare this context for refreshing, setting its startup date and     * active flag as well as performing any initialization of property sources.     */    protected void prepareRefresh() {        // 启动利用开关        this.startupDate = System.currentTimeMillis();        this.closed.set(false);        //设置启动状态        this.active.set(true);        if (logger.isDebugEnabled()) {            if (logger.isTraceEnabled()) {                logger.trace("Refreshing " + this);            }            else {                logger.debug("Refreshing " + getDisplayName());            }        }        // 初始化属性类        initPropertySources();        // 校验属性        // see ConfigurablePropertyResolver#setRequiredProperties        getEnvironment().validateRequiredProperties();        // Store pre-refresh ApplicationListeners...        if (this.earlyApplicationListeners == null) {            this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);        }        else {            // Reset local application listeners to pre-refresh state.            this.applicationListeners.clear();            this.applicationListeners.addAll(this.earlyApplicationListeners);        }        // Allow for the collection of early ApplicationEvents,        // to be published once the multicaster is available...        this.earlyApplicationEvents = new LinkedHashSet<>();    }

在看prepareBeanFactory筹备配置工厂办法

/**     * Configure the factory's standard context characteristics,     * such as the context's ClassLoader and post-processors.     * @param beanFactory the BeanFactory to configure     */    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {        // 设置类加载器        beanFactory.setBeanClassLoader(getClassLoader());        //设置bean表达式解决        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));        //设置属性编辑器注册        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));        // 配置bean处理器,后置解决        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);        // BeanFactory interface not registered as resolvable type in a plain factory.        // MessageSource registered (and found for autowiring) as a bean.        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);        beanFactory.registerResolvableDependency(ResourceLoader.class, this);        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);        beanFactory.registerResolvableDependency(ApplicationContext.class, this);        // 增加事件监听处理器        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));        // Detect a LoadTimeWeaver and prepare for weaving, if found.        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));            // Set a temporary ClassLoader for type matching.            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));        }        // Register default environment beans.        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {    //注册环境bean        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());        }        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {            beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());        }        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {            beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());        }    }

在看postProcessBeanFactory(beanFactory);解决工厂类(子类)

在ServletWebServerApplicationContext类中实现了这个办法    @Override    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {        beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));        beanFactory.ignoreDependencyInterface(ServletContextAware.class);        registerWebApplicationScopes();    }

在看invokeBeanFactoryPostProcessors(beanFactory);调用bean工厂处理器办法

    /**     * Instantiate and invoke all registered BeanFactoryPostProcessor beans,     * respecting explicit order if given.     * <p>Must be called before singleton instantiation.     */    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {//解决工厂类代表    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());        // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime        // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));        }    }

点进去看看

public static void invokeBeanFactoryPostProcessors(            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {        // Invoke BeanDefinitionRegistryPostProcessors first, if any.        Set<String> processedBeans = new HashSet<>();        if (beanFactory instanceof BeanDefinitionRegistry) {            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {                    BeanDefinitionRegistryPostProcessor registryProcessor =                            (BeanDefinitionRegistryPostProcessor) postProcessor;                    registryProcessor.postProcessBeanDefinitionRegistry(registry);                    registryProcessors.add(registryProcessor);                }                else {                    regularPostProcessors.add(postProcessor);                }            }            // Do not initialize FactoryBeans here: We need to leave all regular beans            // uninitialized to let the bean factory post-processors apply to them!            // Separate between BeanDefinitionRegistryPostProcessors that implement            // PriorityOrdered, Ordered, and the rest.            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.            String[] postProcessorNames =                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);            for (String ppName : postProcessorNames) {                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));                    processedBeans.add(ppName);                }            }            sortPostProcessors(currentRegistryProcessors, beanFactory);            registryProcessors.addAll(currentRegistryProcessors);            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);            currentRegistryProcessors.clear();            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);            for (String ppName : postProcessorNames) {                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));                    processedBeans.add(ppName);                }            }            sortPostProcessors(currentRegistryProcessors, beanFactory);            registryProcessors.addAll(currentRegistryProcessors);            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);            currentRegistryProcessors.clear();            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.            boolean reiterate = true;            while (reiterate) {                reiterate = false;                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);                for (String ppName : postProcessorNames) {                    if (!processedBeans.contains(ppName)) {                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));                        processedBeans.add(ppName);                        reiterate = true;                    }                }                sortPostProcessors(currentRegistryProcessors, beanFactory);                registryProcessors.addAll(currentRegistryProcessors);                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);                currentRegistryProcessors.clear();            }            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);        }        else {            // Invoke factory processors registered with the context instance.            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);        }        // Do not initialize FactoryBeans here: We need to leave all regular beans        // uninitialized to let the bean factory post-processors apply to them!        String[] postProcessorNames =                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,        // Ordered, and the rest.        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();        List<String> orderedPostProcessorNames = new ArrayList<>();        List<String> nonOrderedPostProcessorNames = new ArrayList<>();        for (String ppName : postProcessorNames) {            if (processedBeans.contains(ppName)) {                // skip - already processed in first phase above            }            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));            }            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {                orderedPostProcessorNames.add(ppName);            }            else {                nonOrderedPostProcessorNames.add(ppName);            }        }        // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();        for (String postProcessorName : orderedPostProcessorNames) {            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));        }        sortPostProcessors(orderedPostProcessors, beanFactory);        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);        // Finally, invoke all other BeanFactoryPostProcessors.        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();        for (String postProcessorName : nonOrderedPostProcessorNames) {            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));        }        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);        // Clear cached merged bean definitions since the post-processors might have        // modified the original metadata, e.g. replacing placeholders in values...        beanFactory.clearMetadataCache();    }

点进去invokeBeanFactoryPostProcessors办法

    /**     * Invoke the given BeanFactoryPostProcessor beans.     */    private static void invokeBeanFactoryPostProcessors(            Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {        for (BeanFactoryPostProcessor postProcessor : postProcessors) {            postProcessor.postProcessBeanFactory(beanFactory);        }    }

点击postProcessBeanFactory(beanFactory);找到实现类

    @Override    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {        int factoryId = System.identityHashCode(beanFactory);        if (this.factoriesPostProcessed.contains(factoryId)) {            throw new IllegalStateException(                    "postProcessBeanFactory already called on this post-processor against " + beanFactory);        }        this.factoriesPostProcessed.add(factoryId);        if (!this.registriesPostProcessed.contains(factoryId)) {            // BeanDefinitionRegistryPostProcessor hook apparently not supported...            // Simply call processConfigurationClasses lazily at this point then.            processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);        }        enhanceConfigurationClasses(beanFactory);        beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));    }

点击processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);办法找到

// Parse each @Configuration class        ConfigurationClassParser parser = new ConfigurationClassParser(                this.metadataReaderFactory, this.problemReporter, this.environment,                this.resourceLoader, this.componentScanBeanNameGenerator, registry);        Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);        Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());        do {            parser.parse(candidates);            parser.validate();            Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());            configClasses.removeAll(alreadyParsed);

持续找parse办法,找到ConfigurationClassParser类这个办法,接着找

    @Nullable    protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)            throws IOException {

// Process any @Import annotations

    processImports(configClass, sourceClass, getImports(sourceClass), true);    // Process any @ImportResource annotations    AnnotationAttributes importResource =            AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);    if (importResource != null) {        String[] resources = importResource.getStringArray("locations");        Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");        for (String resource : resources) {            String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);            configClass.addImportedResource(resolvedResource, readerClass);        }    }    // Process individual @Bean methods    Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);    for (MethodMetadata methodMetadata : beanMethods) {        configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));    }    // Process default methods on interfaces    processInterfaces(configClass, sourceClass);    // Process superclass, if any    if (sourceClass.getMetadata().hasSuperClass()) {        String superclass = sourceClass.getMetadata().getSuperClassName();        if (superclass != null && !superclass.startsWith("java") &&                !this.knownSuperclasses.containsKey(superclass)) {            this.knownSuperclasses.put(superclass, configClass);            // Superclass found, return its annotation metadata and recurse            return sourceClass.getSuperClass();        }    }    // No superclass -> processing is complete    return null;
咱们找到processImports的解决中央
this.importStack.push(configClass);        try {            for (SourceClass candidate : importCandidates) {                if (candidate.isAssignable(ImportSelector.class)) {                    // Candidate class is an ImportSelector -> delegate to it to determine imports                    Class<?> candidateClass = candidate.loadClass();                    ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);                    ParserStrategyUtils.invokeAwareMethods(                            selector, this.environment, this.resourceLoader, this.registry);                    if (selector instanceof DeferredImportSelector) {                        this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);                    }                    else {                        String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());                        Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);                        processImports(configClass, currentSourceClass, importSourceClasses, false);                    }                }                else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {                    // Candidate class is an ImportBeanDefinitionRegistrar ->                    // delegate to it to register additional bean definitions                    Class<?> candidateClass = candidate.loadClass();                    ImportBeanDefinitionRegistrar registrar =                            BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);                    ParserStrategyUtils.invokeAwareMethods(                            registrar, this.environment, this.resourceLoader, this.registry);                    configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());                }                else {                    // Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->                    // process it as an @Configuration class                    this.importStack.registerImport(                            currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());                    processConfigurationClass(candidate.asConfigClass(configClass));                }            }        }
ImportSelector接口解决的中央,主动配置内部bean的办法接下来,看registerBeanPostProcessors(beanFactory);注册bean处理器工厂而后,看onRefresh办法
@Overrideprotected void onRefresh() {    super.onRefresh();    try {        createWebServer();    }    catch (Throwable ex) {        throw new ApplicationContextException("Unable to start web server", ex);    }}
在这里创立web容器实现刷新,利用启动实现,还有细节结下来在细说。

有问题,请留言! 集体博客地址