{"id":48,"date":"2022-03-19T00:20:32","date_gmt":"2022-03-18T16:20:32","guid":{"rendered":"http:\/\/42.194.186.76:8000\/?p=48"},"modified":"2022-03-19T00:20:32","modified_gmt":"2022-03-18T16:20:32","slug":"spring-boot%e8%87%aa%e5%8a%a8%e9%85%8d%e7%bd%ae%e5%8e%9f%e7%90%86","status":"publish","type":"post","link":"http:\/\/www.fallsky.top\/?p=48","title":{"rendered":"Spring Boot\u81ea\u52a8\u914d\u7f6e\u539f\u7406"},"content":{"rendered":"\n<p>\u200b<\/p>\n\n\n\n<p>&nbsp;1\u3001\u5728Spring Boot\u7684\u542f\u52a8\u8fc7\u7a0b\u4e2d\uff0c\u8981\u8fd0\u884cSpring\u5e94\u7528\u7a0b\u5e8f\uff0c\u521b\u5efa\u5e76\u5237\u65b0\u4e00\u4e2a\u65b0\u7684ApplicationContext\u4e0a\u4e0b\u6587\u3002org.springframework.boot.SpringApplication#run(java.lang.String&#8230;)\u53c2\u6570\u662f\u5e94\u7528\u7a0b\u5e8f\u53c2\u6570\uff0c\u901a\u5e38\u4eceJava\u4e3b\u65b9\u6cd5\u4f20\u9012\u8fc7\u6765\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public ConfigurableApplicationContext run(String... args) {\n    StopWatch stopWatch = new StopWatch();\n    stopWatch.start();\n    DefaultBootstrapContext bootstrapContext = createBootstrapContext();\n    ConfigurableApplicationContext context = null;\n    configureHeadlessProperty();\n    SpringApplicationRunListeners listeners = getRunListeners(args);\n    listeners.starting(bootstrapContext, this.mainApplicationClass);\n    try {\n        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);\n        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);\n        configureIgnoreBeanInfo(environment);\n        Banner printedBanner = printBanner(environment);\n        context = createApplicationContext();\n        context.setApplicationStartup(this.applicationStartup);\n        \/\/ \u6b64\u5904\u5b8c\u6210\u81ea\u52a8\u88c5\u914d\u7684\u8fc7\u7a0b\n        prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);\n        refreshContext(context);\n        afterRefresh(context, applicationArguments);\n        stopWatch.stop();\n        if (this.logStartupInfo) {\n            new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);\n        }\n        listeners.started(context);\n        callRunners(context, applicationArguments);\n    }\n    catch (Throwable ex) {\n        handleRunFailure(context, ex, listeners);\n        throw new IllegalStateException(ex);\n    }\n\n    try {\n        listeners.running(context);\n    }\n    catch (Throwable ex) {\n        handleRunFailure(context, ex, null);\n        throw new IllegalStateException(ex);\n    }\n    return context;\n}<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"15\" src=\"blob:http:\/\/42.194.186.76:8000\/2a36b8e8-ac6b-4baf-8a63-b5c7cd52fe5a\" width=\"15\"><\/p>\n\n\n\n<p>2\u3001\u5728org.springframework.boot.SpringApplication#prepareContext\u65b9\u6cd5\u4e2d\u67e5\u627eload\u65b9\u6cd5\uff0c\u4e00\u5c42\u4e00\u5c42\u5411\u5185\u70b9\u51fb\uff0c\u627e\u5230\u6700\u7ec8\u7684load\u65b9\u6cd5<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,\n                            ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,\n                            ApplicationArguments applicationArguments, Banner printedBanner) {\n    context.setEnvironment(environment);\n    postProcessApplicationContext(context);\n    applyInitializers(context);\n    listeners.contextPrepared(context);\n    bootstrapContext.close(context);\n    if (this.logStartupInfo) {\n        logStartupInfo(context.getParent() == null);\n        logStartupProfileInfo(context);\n    }\n    \/\/ Add boot specific singleton beans\n    ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();\n    beanFactory.registerSingleton(\"springApplicationArguments\", applicationArguments);\n    if (printedBanner != null) {\n        beanFactory.registerSingleton(\"springBootBanner\", printedBanner);\n    }\n    if (beanFactory instanceof DefaultListableBeanFactory) {\n        ((DefaultListableBeanFactory) beanFactory)\n                .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);\n    }\n    if (this.lazyInitialization) {\n        context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());\n    }\n    \/\/ Load the sources\n    Set&lt;Object&gt; sources = getAllSources();\n    Assert.notEmpty(sources, \"Sources must not be empty\");\n    \/\/ load\u65b9\u6cd5\u5b8c\u6210\u8be5\u529f\u80fd\n    load(context, sources.toArray(new Object&#91;0]));\n    listeners.contextLoaded(context);\n}\n\n\/**\n * \u5c06bean\u52a0\u8f7d\u5230\u5e94\u7528\u7a0b\u5e8f\u4e0a\u4e0b\u6587\u4e2d\u3002\n * @param context \u52a0\u8f7dbean\u7684\u4e0a\u4e0b\u6587\n * @param sources \u8981\u52a0\u8f7d\u7684\u8d44\u6e90\n *\/\nprotected void load(ApplicationContext context, Object&#91;] sources) {\n    if (logger.isDebugEnabled()) {\n        logger.debug(\"Loading source \" + StringUtils.arrayToCommaDelimitedString(sources));\n    }\n    \/\/ \u83b7\u53d6bean\u5bf9\u8c61\u5b9a\u4e49\u7684\u52a0\u8f7d\u5668\n    BeanDefinitionLoader loader = createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);\n    if (this.beanNameGenerator != null) {\n        loader.setBeanNameGenerator(this.beanNameGenerator);\n    }\n    if (this.resourceLoader != null) {\n        loader.setResourceLoader(this.resourceLoader);\n    }\n    if (this.environment != null) {\n        loader.setEnvironment(this.environment);\n    }\n    loader.load();\n}<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"15\" src=\"blob:http:\/\/42.194.186.76:8000\/63b86a80-ae5b-4bd6-8f92-13cc7afa81e5\" width=\"15\"><\/p>\n\n\n\n<p>3\u3001\u5b9e\u9645\u6267\u884cload\u7684\u662forg.springframework.boot.BeanDefinitionLoader#load(java.lang.Object)\u65b9\u6cd5\uff0c\u5982\u4e0b\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>private void load(Object source) {\n    Assert.notNull(source, \"Source must not be null\");\n    \/\/ \u5982\u679c\u662f Class \u7c7b\u578b\uff0c\u542f\u7528\u6ce8\u89e3\u7c7b\u578b\n    if (source instanceof Class&lt;?&gt;) {\n        load((Class&lt;?&gt;) source);\n        return;\n    }\n    \/\/ \u5982\u679c\u662f Resource \u7c7b\u578b\uff0c\u542f\u52a8 XML \u89e3\u6790\n    if (source instanceof Resource) {\n        load((Resource) source);\n        return;\n    }\n    \/\/ \u5982\u679c\u662f Package \u7c7b\u578b\uff0c\u542f\u7528\u626b\u63cf\u5305\uff0c\u4f8b\u5982 @ComponentScan\n    if (source instanceof Package) {\n        load((Package) source);\n        return;\n    }\n    \/\/ \u5982\u679c\u662f\u5b57\u7b26\u4e32\u7c7b\u578b\uff0c\u76f4\u63a5\u52a0\u8f7d\n    if (source instanceof CharSequence) {\n        load((CharSequence) source);\n        return;\n    }\n    throw new IllegalArgumentException(\"Invalid source type \" + source.getClass());\n}<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"15\" src=\"blob:http:\/\/42.194.186.76:8000\/6ef602a5-e5db-4546-b754-437c5adb06e6\" width=\"15\"><\/p>\n\n\n\n<p>4\u3001\u4e0b\u9762\u65b9\u6cd5\u5c06\u7528\u6765\u5224\u65ad\u662f\u5426\u8d44\u6e90\u7684\u7c7b\u578b\uff0c\u662f\u4f7f\u7528groovy\u52a0\u8f7d\u8fd8\u662f\u4f7f\u7528\u6ce8\u89e3\u7684\u65b9\u5f0f<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>private void load(Class&lt;?&gt; source) {\n    \/\/ \u5224\u65ad\u4f7f\u7528 groovy \u811a\u672c\n    if (isGroovyPresent() &amp;&amp; BeanDefinitionLoader.GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {\n        \/\/ Any GroovyLoaders added in beans{} DSL can contribute beans here\n        BeanDefinitionLoader.GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, BeanDefinitionLoader.GroovyBeanDefinitionSource.class);\n        ((GroovyBeanDefinitionReader) this.groovyReader).beans(loader.getBeans());\n    }\n    \/\/ \u4f7f\u7528\u6ce8\u89e3\u52a0\u8f7d\n    if (isEligible(source)) {\n        this.annotatedReader.register(source);\n    }\n}<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"15\" src=\"blob:http:\/\/42.194.186.76:8000\/f6a95d34-261d-4ee3-ba42-009296f0e96d\" width=\"15\"><\/p>\n\n\n\n<p>5\u3001\u4e0b\u9762\u65b9\u6cd5\u5224\u65ad\u542f\u52a8\u7c7b\u4e2d\u662f\u5426\u5305\u542b@Component\u6ce8\u89e3\uff0c\u4f46\u662f\u4f1a\u795e\u5947\u5730\u53d1\u73b0\u6211\u4eec\u7684\u542f\u52a8\u7c7b\u4e2d\u5e76\u6ca1\u6709\u8be5\u6ce8\u89e3\uff0c\u7ee7\u7eed\u8ddf\u8fdb\u53d1\u73b0MergedAnnotations\u7c7b\u4f20\u5165\u4e86\u4e00\u4e2a\u53c2\u6570SearchStrategy.TYPE_HIERARCHY\uff0c\u4f1a\u67e5\u627e\u7ee7\u627f\u5173\u7cfb\u4e2d\u662f\u5426\u5305\u542b\u8fd9\u4e2a\u6ce8\u89e3\uff0c@SpringBootApplication &#8211;&gt; @SpringBootConfiguration &#8211;&gt; @Configuration &#8211;&gt; @Component\uff0c\u5f53\u627e\u5230@Component\u6ce8\u89e3\u4e4b\u540e\uff0c\u4f1a\u628a\u8be5\u5bf9\u8c61\u6ce8\u518c\u5230AnnotatedBeanDefinitionReader\u5bf9\u8c61\u4e2d<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ org.springframework.boot.context.properties.ConfigurationPropertiesScanRegistrar#isComponent\nprivate boolean isComponent(Class&lt;?&gt; type) {\n    return MergedAnnotations.from(type, SearchStrategy.TYPE_HIERARCHY).isPresent(Component.class);\n}\n\n\/**\n * \u4ece\u7ed9\u5b9a\u7684bean\u7c7b\u6ce8\u518c\u4e00\u4e2abean\uff0c\u4ece\u7c7b\u58f0\u660e\u7684\u6ce8\u91ca\u6d3e\u751f\u5b83\u7684\u5143\u6570\u636e\u3002\n * org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean(java.lang.Class, java.lang.String, java.lang.Class&#91;], java.util.function.Supplier, org.springframework.beans.factory.config.BeanDefinitionCustomizer&#91;])\n * @param beanClass bean\u7684\u7c7b\n * @param name bean\u7684\u663e\u5f0f\u540d\u79f0\n * @param qualifiers \u9664\u4e86bean\u7c7b\u7ea7\u522b\u7684\u9650\u5b9a\u7b26\u4e4b\u5916\uff0c\u8fd8\u8981\u8003\u8651\u7279\u5b9a\u7684\u9650\u5b9a\u7b26\u6ce8\u91ca(\u5982\u679c\u6709\u7684\u8bdd)\n * @param supplier \u7528\u4e8e\u521b\u5efabean\u5b9e\u4f8b\u7684\u56de\u8c03(\u53ef\u80fd\u4e3a\u7a7a)\n * @param customizers \u4e00\u4e2a\u6216\u591a\u4e2a\u56de\u8c03\u51fd\u6570\u7528\u4e8e\u81ea\u5b9a\u4e49\u5de5\u5382\u7684bean\u5b9a\u4e49\uff0c\u4f8b\u5982\u8bbe\u7f6elazy-init\u6216primary\u6807\u5fd7\n *\/\nprivate &lt;T&gt; void doRegisterBean(Class&lt;T&gt; beanClass, @Nullable String name,\n                                @Nullable Class&lt;? extends Annotation&gt;&#91;] qualifiers, @Nullable Supplier&lt;T&gt; supplier,\n                                @Nullable BeanDefinitionCustomizer&#91;] customizers) {\n\n    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);\n    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {\n        return;\n    }\n\n    abd.setInstanceSupplier(supplier);\n    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);\n    abd.setScope(scopeMetadata.getScopeName());\n    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));\n\n    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);\n    if (qualifiers != null) {\n        for (Class&lt;? extends Annotation&gt; qualifier : qualifiers) {\n            if (Primary.class == qualifier) {\n                abd.setPrimary(true);\n            }\n            else if (Lazy.class == qualifier) {\n                abd.setLazyInit(true);\n            }\n            else {\n                abd.addQualifier(new AutowireCandidateQualifier(qualifier));\n            }\n        }\n    }\n    if (customizers != null) {\n        for (BeanDefinitionCustomizer customizer : customizers) {\n            customizer.customize(abd);\n        }\n    }\n\n    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);\n    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);\n    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);\n}\n\n\/**\n * \u5c06\u7ed9\u5b9a\u7684bean\u5b9a\u4e49\u6ce8\u518c\u5230\u7ed9\u5b9a\u7684bean\u5de5\u5382\u3002\n * org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition(org.springframework.beans.factory.config.BeanDefinitionHolder, org.springframework.beans.factory.support.BeanDefinitionRegistry)\n * @param definitionHolder bean\u5b9a\u4e49\u5305\u62ec\u540d\u79f0\u548c\u522b\u540d\n * @param registry \u8981\u6ce8\u518c\u7684bean\u5de5\u5382\n * @throws BeanDefinitionStoreException \u5982\u679c\u6ce8\u518c\u5931\u8d25\n *\/\npublic static void registerBeanDefinition(\n        BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)\n        throws BeanDefinitionStoreException {\n\n    \/\/ Register bean definition under primary name.\n    String beanName = definitionHolder.getBeanName();\n    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());\n\n    \/\/ Register aliases for bean name, if any.\n    String&#91;] aliases = definitionHolder.getAliases();\n    if (aliases != null) {\n        for (String alias : aliases) {\n            registry.registerAlias(beanName, alias);\n        }\n    }\n}\n\n\/\/ org.springframework.boot.autoconfigure.SpringBootApplication\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\n@Inherited\n@SpringBootConfiguration\n@EnableAutoConfiguration\n@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),\n\t\t@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })\npublic @interface SpringBootApplication {...}\n\n\/\/ org.springframework.boot.SpringBootConfiguration\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\n@Configuration\n@Indexed\npublic @interface SpringBootConfiguration {...}\n\n\/\/ org.springframework.context.annotation.Configuration\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\n@Component\npublic @interface Configuration {...}<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"15\" src=\"blob:http:\/\/42.194.186.76:8000\/fc32c176-40bd-4072-89e4-871e9c898ea2\" width=\"15\"><\/p>\n\n\n\n<p>\u5f53\u770b\u5b8c\u4e0a\u8ff0\u4ee3\u7801\u4e4b\u540e\uff0c\u53ea\u662f\u5b8c\u6210\u4e86\u542f\u52a8\u5bf9\u8c61\u7684\u6ce8\u5165\uff0c\u81ea\u52a8\u88c5\u914d\u8fd8\u6ca1\u6709\u5f00\u59cb\uff0c\u4e0b\u9762\u5f00\u59cb\u8fdb\u5165\u5230\u81ea\u52a8\u88c5\u914d\u3002<\/p>\n\n\n\n<p>6\u3001\u81ea\u52a8\u88c5\u914d\u5165\u53e3\uff0c\u4ece\u5237\u65b0\u5bb9\u5668\u5f00\u59cb<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ org.springframework.context.support.AbstractApplicationContext#refresh\n@Override\npublic void refresh() throws BeansException, IllegalStateException {\n    synchronized (this.startupShutdownMonitor) {\n        StartupStep contextRefresh = this.applicationStartup.start(\"spring.context.refresh\");\n\n        \/\/ Prepare this context for refreshing.\n        prepareRefresh();\n\n        \/\/ Tell the subclass to refresh the internal bean factory.\n        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();\n\n        \/\/ Prepare the bean factory for use in this context.\n        prepareBeanFactory(beanFactory);\n\n        try {\n            \/\/ Allows post-processing of the bean factory in context subclasses.\n            postProcessBeanFactory(beanFactory);\n\n            StartupStep beanPostProcess = this.applicationStartup.start(\"spring.context.beans.post-process\");\n            \/\/ Invoke factory processors registered as beans in the context.\n            \/\/ \u6b64\u5904\u662f\u81ea\u52a8\u88c5\u914d\u7684\u5165\u53e3\n            invokeBeanFactoryPostProcessors(beanFactory);\n            ...\n        }\n\n        catch (BeansException ex) {\n            ...\n        }\n\n        finally {\n            ...\n        }\n    }\n}<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"15\" src=\"blob:http:\/\/42.194.186.76:8000\/324c49ce-2178-457b-bcf6-67fa6bb69837\" width=\"15\"><\/p>\n\n\n\n<p>7\u3001\u5728invokeBeanFactoryPostProcessors\u65b9\u6cd5\u4e2d\u5b8c\u6210bean\u7684\u5b9e\u4f8b\u5316\u548c\u6267\u884c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/**\n * \u5b9e\u4f8b\u5316\u548c\u8c03\u7528\u6240\u6709\u5df2\u6ce8\u518c\u7684BeanFactoryPostProcessor bean\uff0c\u5982\u679c\u7ed9\u5b9a\u4e86\u660e\u786e\u7684\u987a\u5e8f\u3002\n * \u5fc5\u987b\u5728\u5355\u4f8b\u5b9e\u4f8b\u5316\u4e4b\u524d\u8c03\u7528\u3002\n *\/\nprotected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {\n    \/\/ \u5f00\u59cb\u6267\u884c beanFactoryPostProcessors \u5bf9\u5e94\u5b9e\u73b0\u7c7b\uff0c\u9700\u8981\u77e5\u9053\u7684\u662f beanFactoryPostProcessors \u662f Spring \u7684\u6269\u5c55\u63a5\u53e3\uff0c\u5728\u5237\u65b0\u5bb9\u5668\u4e4b\u524d\uff0c\u8be5\u63a5\u53e3\u53ef\u4ee5\u7528\u6765\u4fee\u6539 bean \u5143\u6570\u636e\u4fe1\u606f\n    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());\n\n    \/\/ Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime\n    \/\/ (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)\n    if (!NativeDetector.inNativeImage() &amp;&amp; beanFactory.getTempClassLoader() == null &amp;&amp; beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {\n        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));\n        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));\n    }\n}<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"15\" src=\"blob:http:\/\/42.194.186.76:8000\/254958da-422b-410d-9b46-eb612e8a240d\" width=\"15\"><\/p>\n\n\n\n<p>8\u3001\u67e5\u770binvokeBeanFactoryPostProcessors\u7684\u5177\u4f53\u6267\u884c\u65b9\u6cd5<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List&lt;org.springframework.beans.factory.config.BeanFactoryPostProcessor&gt;)\npublic static void invokeBeanFactoryPostProcessors(\n        ConfigurableListableBeanFactory beanFactory, List&lt;BeanFactoryPostProcessor&gt; beanFactoryPostProcessors) {\n\n    \/\/ Invoke BeanDefinitionRegistryPostProcessors first, if any.\n    Set&lt;String&gt; processedBeans = new HashSet&lt;&gt;();\n\n    if (beanFactory instanceof BeanDefinitionRegistry) {\n        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;\n        List&lt;BeanFactoryPostProcessor&gt; regularPostProcessors = new ArrayList&lt;&gt;();\n        List&lt;BeanDefinitionRegistryPostProcessor&gt; registryProcessors = new ArrayList&lt;&gt;();\n        \/\/ \u5f00\u59cb\u904d\u5386\u4e09\u4e2a\u5185\u90e8\u7c7b\uff0c\u5982\u679c\u5c5e\u4e8e BeanDefinitionRegistryPostProcessor \u5b50\u7c7b\uff0c\u52a0\u5165\u5230 bean \u6ce8\u518c\u7684\u96c6\u5408\uff0c\u5426\u5219\u52a0\u5165\u5230 regularPostProcessors\n        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {\n            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {\n                BeanDefinitionRegistryPostProcessor registryProcessor =\n                        (BeanDefinitionRegistryPostProcessor) postProcessor;\n                registryProcessor.postProcessBeanDefinitionRegistry(registry);\n                registryProcessors.add(registryProcessor);\n            }\n            else {\n                regularPostProcessors.add(postProcessor);\n            }\n        }\n\n        \/\/ Do not initialize FactoryBeans here: We need to leave all regular beans\n        \/\/ uninitialized to let the bean factory post-processors apply to them!\n        \/\/ Separate between BeanDefinitionRegistryPostProcessors that implement\n        \/\/ PriorityOrdered, Ordered, and the rest.\n        List&lt;BeanDefinitionRegistryPostProcessor&gt; currentRegistryProcessors = new ArrayList&lt;&gt;();\n\n        \/\/ First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.\n        String&#91;] postProcessorNames =\n                beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);\n        \/\/ \u9996\u5148\u6267\u884c\u7c7b\u578b\u4e3a PriorityOrdered \u7684 BeanDefinitionRegistryPostProcessor\n        \/\/ PriorityOrdered \u7c7b\u578b\u8868\u660e\u4e3a\u4f18\u5148\u6267\u884c\n        for (String ppName : postProcessorNames) {\n            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {\n                \/\/ \u83b7\u53d6\u5bf9\u5e94\u7684 bean\n                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));\n                \/\/ \u7528\u6765\u5b58\u50a8\u5df2\u7ecf\u6267\u884c\u8fc7\u7684 BeanDefinitionRegistryPostProcessor\n                processedBeans.add(ppName);\n            }\n        }\n        sortPostProcessors(currentRegistryProcessors, beanFactory);\n        registryProcessors.addAll(currentRegistryProcessors);\n        \/\/ \u5f00\u59cb\u6267\u884c\u88c5\u914d\u903b\u8f91\n        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());\n        currentRegistryProcessors.clear();\n\n        \/\/ Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.\n        \/\/ \u5176\u6b21\u6267\u884c\u7c7b\u578b\u4e3a Ordered \u7684 BeanDefinitionRegistryPostProcessor\n        \/\/ Ordered \u8868\u660e\u6309\u987a\u5e8f\u6267\u884c\n        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);\n        for (String ppName : postProcessorNames) {\n            if (!processedBeans.contains(ppName) &amp;&amp; beanFactory.isTypeMatch(ppName, Ordered.class)) {\n                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));\n                processedBeans.add(ppName);\n            }\n        }\n        sortPostProcessors(currentRegistryProcessors, beanFactory);\n        registryProcessors.addAll(currentRegistryProcessors);\n        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());\n        currentRegistryProcessors.clear();\n\n        \/\/ Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.\n        \/\/ \u5faa\u73af\u4e2d\u6267\u884c\u7c7b\u578b\u4e0d\u4e3a PriorityOrdered\u3001Ordered \u7c7b\u578b\u7684 BeanDefinitionRegistryPostProcessor\n        boolean reiterate = true;\n        while (reiterate) {\n            reiterate = false;\n            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);\n            for (String ppName : postProcessorNames) {\n                if (!processedBeans.contains(ppName)) {\n                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));\n                    processedBeans.add(ppName);\n                    reiterate = true;\n                }\n            }\n            sortPostProcessors(currentRegistryProcessors, beanFactory);\n            registryProcessors.addAll(currentRegistryProcessors);\n            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());\n            currentRegistryProcessors.clear();\n        }\n\n        \/\/ Now, invoke the postProcessBeanFactory callback of all processors handled so far.\n        \/\/ \u6267\u884c\u7236\u7c7b\u65b9\u6cd5\uff0c\u4f18\u5148\u6267\u884c\u6ce8\u518c\u5904\u7406\u7c7b\n        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);\n        \/\/ \u6267\u884c\u6709\u89c4\u5219\u5904\u7406\u7c7b\n        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);\n    }\n\n    else {\n        \/\/ Invoke factory processors registered with the context instance.\n        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);\n    }\n\n    \/\/ Do not initialize FactoryBeans here: We need to leave all regular beans\n    \/\/ uninitialized to let the bean factory post-processors apply to them!\n    String&#91;] postProcessorNames =\n            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);\n\n    \/\/ Separate between BeanFactoryPostProcessors that implement PriorityOrdered,\n    \/\/ Ordered, and the rest.\n    List&lt;BeanFactoryPostProcessor&gt; priorityOrderedPostProcessors = new ArrayList&lt;&gt;();\n    List&lt;String&gt; orderedPostProcessorNames = new ArrayList&lt;&gt;();\n    List&lt;String&gt; nonOrderedPostProcessorNames = new ArrayList&lt;&gt;();\n    for (String ppName : postProcessorNames) {\n        if (processedBeans.contains(ppName)) {\n            \/\/ skip - already processed in first phase above\n        }\n        else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {\n            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));\n        }\n        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {\n            orderedPostProcessorNames.add(ppName);\n        }\n        else {\n            nonOrderedPostProcessorNames.add(ppName);\n        }\n    }\n\n    \/\/ First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.\n    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);\n    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);\n\n    \/\/ Next, invoke the BeanFactoryPostProcessors that implement Ordered.\n    List&lt;BeanFactoryPostProcessor&gt; orderedPostProcessors = new ArrayList&lt;&gt;(orderedPostProcessorNames.size());\n    for (String postProcessorName : orderedPostProcessorNames) {\n        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));\n    }\n    sortPostProcessors(orderedPostProcessors, beanFactory);\n    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);\n\n    \/\/ Finally, invoke all other BeanFactoryPostProcessors.\n    List&lt;BeanFactoryPostProcessor&gt; nonOrderedPostProcessors = new ArrayList&lt;&gt;(nonOrderedPostProcessorNames.size());\n    for (String postProcessorName : nonOrderedPostProcessorNames) {\n        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));\n    }\n    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);\n\n    \/\/ Clear cached merged bean definitions since the post-processors might have\n    \/\/ modified the original metadata, e.g. replacing placeholders in values...\n    beanFactory.clearMetadataCache();\n}<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"15\" src=\"blob:http:\/\/42.194.186.76:8000\/bd3b78c7-620a-4c88-ac14-4235f9ff1fdd\" width=\"15\"><\/p>\n\n\n\n<p>9\u3001\u5f00\u59cb\u6267\u884c\u81ea\u52a8\u914d\u7f6e\u903b\u8f91\uff08\u542f\u52a8\u7c7b\u6307\u5b9a\u7684\u914d\u7f6e\uff0c\u975e\u9ed8\u8ba4\u914d\u7f6e\uff09\uff0c\u53ef\u4ee5\u901a\u8fc7debug\u7684\u65b9\u5f0f\u4e00\u5c42\u5c42\u5411\u91cc\u8fdb\u884c\u67e5\u627e\uff0c\u4f1a\u53d1\u73b0\u6700\u7ec8\u4f1a\u5728ConfigurationClassParser\u7c7b\u4e2d\uff0c\u6b64\u7c7b\u662f\u6240\u6709\u914d\u7f6e\u7c7b\u7684\u89e3\u6790\u7c7b\uff0c\u6240\u6709\u7684\u89e3\u6790\u903b\u8f91\u5728org.springframework.context.annotation.ConfigurationClassParser#parse(java.util.Set&lt;org.springframework.beans.factory.config.BeanDefinitionHolder&gt;)\u4e2d<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public void parse(Set&lt;BeanDefinitionHolder&gt; configCandidates) {\n    for (BeanDefinitionHolder holder : configCandidates) {\n        BeanDefinition bd = holder.getBeanDefinition();\n        try {\n            \/\/ \u662f\u5426\u662f\u6ce8\u89e3\u7c7b\n            if (bd instanceof AnnotatedBeanDefinition) {\n                parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());\n            }\n            else if (bd instanceof AbstractBeanDefinition &amp;&amp; ((AbstractBeanDefinition) bd).hasBeanClass()) {\n                parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());\n            }\n            else {\n                parse(bd.getBeanClassName(), holder.getBeanName());\n            }\n        }\n        catch (BeanDefinitionStoreException ex) {\n            throw ex;\n        }\n        catch (Throwable ex) {\n            throw new BeanDefinitionStoreException(\n                    \"Failed to parse configuration class &#91;\" + bd.getBeanClassName() + \"]\", ex);\n        }\n    }\n    \/\/ \u6267\u884c\u914d\u7f6e\u7c7b\n    this.deferredImportSelectorHandler.process();\n}\n\nprotected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {\n    processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);\n}\n\nprotected void processConfigurationClass(ConfigurationClass configClass, Predicate&lt;String&gt; filter) throws IOException {\n    if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {\n        return;\n    }\n\n    ConfigurationClass existingClass = this.configurationClasses.get(configClass);\n    if (existingClass != null) {\n        if (configClass.isImported()) {\n            if (existingClass.isImported()) {\n                existingClass.mergeImportedBy(configClass);\n            }\n            \/\/ Otherwise ignore new imported config class; existing non-imported class overrides it.\n            return;\n        }\n        else {\n            \/\/ Explicit bean definition found, probably replacing an import.\n            \/\/ Let's remove the old one and go with the new one.\n            this.configurationClasses.remove(configClass);\n            this.knownSuperclasses.values().removeIf(configClass::equals);\n        }\n    }\n\n    \/\/ Recursively process the configuration class and its superclass hierarchy.\n    ConfigurationClassParser.SourceClass sourceClass = asSourceClass(configClass, filter);\n    do {\n        \/\/ \u5faa\u73af\u5904\u7406 bean\uff0c\u5982\u679c\u6709\u7236\u7c7b\uff0c\u5219\u5904\u7406\u7236\u7c7b\uff0c\u76f4\u81f3\u7ed3\u675f\n        sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);\n    }\n    while (sourceClass != null);\n\n    this.configurationClasses.put(configClass, configClass);\n}<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"15\" src=\"blob:http:\/\/42.194.186.76:8000\/0cb30d69-f4c2-41d8-a189-06d779f9ab8a\" width=\"15\"><\/p>\n\n\n\n<p>10\u3001\u7ee7\u7eed\u8ddf\u8fdbdoProcessConfigurationClass\u65b9\u6cd5\uff0c\u6b64\u65b9\u5f0f\u662f\u652f\u6301\u6ce8\u89e3\u914d\u7f6e\u7684\u6838\u5fc3\u903b\u8f91<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/**\n * \u901a\u8fc7\u4ece\u6e90\u7c7b\u8bfb\u53d6\u6ce8\u91ca\u3001\u6210\u5458\u548c\u65b9\u6cd5\uff0c\u5e94\u7528\u5904\u7406\u5e76\u6784\u5efa\u4e00\u4e2a\u5b8c\u6574\u7684ConfigurationClass\u3002\u5f53\u53d1\u73b0\u76f8\u5173\u6e90\u65f6\uff0c\u53ef\u4ee5\u591a\u6b21\u8c03\u7528\u8be5\u65b9\u6cd5\u3002\n * @param configClass \u6b63\u5728\u6784\u5efa\u7684\u914d\u7f6e\u7c7b\n * @return \u8d85\u7c7b\uff0c\u5982\u679c\u6ca1\u6709\u53d1\u73b0\u6216\u4e4b\u524d\u5904\u7406\u8fc7\uff0c\u5219\u4e3a\u7a7a\n *\/\n@Nullable\nprotected final SourceClass doProcessConfigurationClass(\n        ConfigurationClass configClass, SourceClass sourceClass, Predicate&lt;String&gt; filter)\n        throws IOException {\n\n    \/\/ \u5904\u7406\u5185\u90e8\u7c7b\u903b\u8f91\uff0c\u7531\u4e8e\u4f20\u6765\u7684\u53c2\u6570\u662f\u542f\u52a8\u7c7b\uff0c\u5e76\u4e0d\u5305\u542b\u5185\u90e8\u7c7b\uff0c\u6240\u4ee5\u8e22\u554a\u5076\u54e6 \n    if (configClass.getMetadata().isAnnotated(Component.class.getName())) {\n        \/\/ Recursively process any member (nested) classes first\n        processMemberClasses(configClass, sourceClass, filter);\n    }\n\n    \/\/ Process any @PropertySource annotations\n    \/\/ \u9488\u5bf9\u5c5e\u6027\u914d\u7f6e\u7684\u89e3\u6790\n    for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(\n            sourceClass.getMetadata(), PropertySources.class,\n            org.springframework.context.annotation.PropertySource.class)) {\n        if (this.environment instanceof ConfigurableEnvironment) {\n            processPropertySource(propertySource);\n        }\n        else {\n            logger.info(\"Ignoring @PropertySource annotation on &#91;\" + sourceClass.getMetadata().getClassName() +\n                    \"]. Reason: Environment must implement ConfigurableEnvironment\");\n        }\n    }\n\n    \/\/ Process any @ComponentScan annotations\n    \/\/ \u8fd9\u91cc\u662f\u6839\u636e\u542f\u52a8\u7c7b @ComponentScan \u6ce8\u89e3\u6765\u626b\u63cf\u9879\u76ee\u4e2d\u7684 bean\n    Set&lt;AnnotationAttributes&gt; componentScans = AnnotationConfigUtils.attributesForRepeatable(\n            sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);\n    if (!componentScans.isEmpty() &amp;&amp;\n            !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {\n        for (AnnotationAttributes componentScan : componentScans) {\n            \/\/ The config class is annotated with @ComponentScan -&gt; perform the scan immediately\n            \/\/ \u904d\u5386\u9879\u76ee\u4e2d\u7684 bean\uff0c\u5982\u679c\u662f\u6ce8\u89e3\u5b9a\u4e49\u7684bean\uff0c\u5219\u8fdb\u4e00\u6b65\u89e3\u6790\n            Set&lt;BeanDefinitionHolder&gt; scannedBeanDefinitions =\n                    this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());\n            \/\/ Check the set of scanned definitions for any further config classes and parse recursively if needed\n            for (BeanDefinitionHolder holder : scannedBeanDefinitions) {\n                BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();\n                if (bdCand == null) {\n                    bdCand = holder.getBeanDefinition();\n                }\n                if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {\n                    \/\/ \u9012\u5f52\u89e3\u6790\uff0c\u6240\u6709\u7684 bean\uff0c\u5982\u679c\u6709\u6ce8\u89e3\uff0c\u4f1a\u8fdb\u4e00\u6b65\u89e3\u6790\u6ce8\u89e3\u4e2d\u5305\u542b\u7684 bean\n                    parse(bdCand.getBeanClassName(), holder.getBeanName());\n                }\n            }\n        }\n    }\n\n    \/\/ Process any @Import annotations\n    \/\/ \u9012\u5f52\u89e3\u6790\uff0c\u83b7\u53d6\u5bfc\u5165\u7684\u914d\u7f6e\u7c7b\uff0c\u5f88\u591a\u60c5\u51b5\u4e0b\uff0c\u5bfc\u5165\u7684\u914d\u7f6e\u7c7b\u4e2d\u4f1a\u540c\u6837\u5305\u542b\u5bfc\u5165\u7c7b\u6ce8\u89e3\n    processImports(configClass, sourceClass, getImports(sourceClass), filter, true);\n\n    \/\/ Process any @ImportResource annotations\n    \/\/ \u89e3\u6790 @ImportResource \u914d\u7f6e\u7c7b\n    AnnotationAttributes importResource =\n            AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);\n    if (importResource != null) {\n        String&#91;] resources = importResource.getStringArray(\"locations\");\n        Class&lt;? extends BeanDefinitionReader&gt; readerClass = importResource.getClass(\"reader\");\n        for (String resource : resources) {\n            String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);\n            configClass.addImportedResource(resolvedResource, readerClass);\n        }\n    }\n\n    \/\/ Process individual @Bean methods\n    \/\/ \u5904\u7406 @Bean \u6ce8\u89e3\u4fee\u9970\u7684\u7c7b\n    Set&lt;MethodMetadata&gt; beanMethods = retrieveBeanMethodMetadata(sourceClass);\n    for (MethodMetadata methodMetadata : beanMethods) {\n        configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));\n    }\n\n    \/\/ Process default methods on interfaces\n    \/\/ \u5904\u7406\u63a5\u53e3\u4e2d\u7684\u9ed8\u8ba4\u65b9\u6cd5\n    processInterfaces(configClass, sourceClass);\n\n    \/\/ Process superclass, if any\n    \/\/ \u5982\u679c\u8be5\u7c7b\u6709\u7236\u7c7b\uff0c\u5219\u7ee7\u7eed\u8fd4\u56de\uff0c\u4e0a\u5c42\u65b9\u6cd5\u5224\u65ad\u4e0d\u4e3a\u7a7a\uff0c\u5219\u7ee7\u7eed\u9012\u5f52\u6267\u884c\n    if (sourceClass.getMetadata().hasSuperClass()) {\n        String superclass = sourceClass.getMetadata().getSuperClassName();\n        if (superclass != null &amp;&amp; !superclass.startsWith(\"java\") &amp;&amp;\n                !this.knownSuperclasses.containsKey(superclass)) {\n            this.knownSuperclasses.put(superclass, configClass);\n            \/\/ Superclass found, return its annotation metadata and recurse\n            return sourceClass.getSuperClass();\n        }\n    }\n\n    \/\/ No superclass -&gt; processing is complete\n    return null;\n}<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"15\" src=\"blob:http:\/\/42.194.186.76:8000\/9656bfab-a88a-42c2-84ca-c85a06004e36\" width=\"15\"><\/p>\n\n\n\n<p>11\u3001\u67e5\u770b\u83b7\u53d6\u914d\u7f6e\u7c7b\u7684\u903b\u8f91<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>processImports(configClass, sourceClass, getImports(sourceClass), filter, true);\n\n\/**\n * \u8fd4\u56de@Import\u7c7b\uff0c\u8003\u8651\u6240\u6709\u7684\u5143\u6ce8\u89e3\u3002\n *\/\nprivate Set&lt;SourceClass&gt; getImports(SourceClass sourceClass) throws IOException {\n    Set&lt;SourceClass&gt; imports = new LinkedHashSet&lt;&gt;();\n    Set&lt;SourceClass&gt; visited = new LinkedHashSet&lt;&gt;();\n    collectImports(sourceClass, imports, visited);\n    return imports;\n}\n\n\/**\n * \u9012\u5f52\u5730\u6536\u96c6\u6240\u6709\u58f0\u660e\u7684@Import\u503c\u3002\u4e0e\u5927\u591a\u6570\u5143\u6ce8\u91ca\u4e0d\u540c\u7684\u662f\uff0c\u4f7f\u7528\u4e0d\u540c\u7684\u503c\u58f0\u660e\u51e0\u4e2a@Imports\u662f\u6709\u6548\u7684;\u901a\u5e38\u4ece\u7c7b\u7684\u7b2c\u4e00\u4e2a\u5143\u6ce8\u91ca\u8fd4\u56de\u503c\u7684\u8fc7\u7a0b\u662f\u4e0d\u591f\u7684\u3002\n * \u4f8b\u5982\uff0c\u9664\u4e86\u6e90\u81ea@Enable\u6ce8\u91ca\u7684\u5143\u5bfc\u5165\u4e4b\u5916\uff0c@Configuration\u7c7b\u901a\u5e38\u8fd8\u58f0\u660e\u76f4\u63a5\u7684@Imports\u3002\n * @param sourceClass \u8981\u641c\u7d22\u7684\u7c7b\n * @param imports \u5230\u76ee\u524d\u4e3a\u6b62\u7684\u8fdb\u53e3\u989d\n * @param visited \u7528\u4e8e\u8ddf\u8e2a\u8bbf\u95ee\u7684\u7c7b\uff0c\u4ee5\u9632\u6b62\u65e0\u9650\u9012\u5f52\n * @throws IOException \u5982\u679c\u4ece\u6307\u5b9a\u7684\u7c7b\u8bfb\u53d6\u5143\u6570\u636e\u6709\u4efb\u4f55\u95ee\u9898\n *\/\nprivate void collectImports(SourceClass sourceClass, Set&lt;SourceClass&gt; imports, Set&lt;SourceClass&gt; visited)\n        throws IOException {\n\n    if (visited.add(sourceClass)) {\n        for (SourceClass annotation : sourceClass.getAnnotations()) {\n            String annName = annotation.getMetadata().getClassName();\n            if (!annName.equals(Import.class.getName())) {\n                collectImports(annotation, imports, visited);\n            }\n        }\n        imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), \"value\"));\n    }\n}<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"15\" src=\"blob:http:\/\/42.194.186.76:8000\/ebc9e4e3-37bd-4589-9d8b-b7d2d3cb7e25\" width=\"15\"><\/p>\n\n\n\n<p>12\u3001\u7ee7\u7eed\u8fd4\u56de\u5230org.springframework.context.annotation.ConfigurationClassParser#parse(java.util.Set&lt;org.springframework.beans.factory.config.BeanDefinitionHolder&gt;)\u65b9\u6cd5\u4e2d\u7684\u6700\u540e\u9057\u61be\uff0c\u7ee7\u7eed\u8ddf\u8fdb\u8be5\u65b9\u6cd5\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>this.deferredImportSelectorHandler.process();\n\npublic void process() {\n    List&lt;DeferredImportSelectorHolder&gt; deferredImports = this.deferredImportSelectors;\n    this.deferredImportSelectors = null;\n    try {\n        if (deferredImports != null) {\n            DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();\n            deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);\n            deferredImports.forEach(handler::register);\n            handler.processGroupImports();\n        }\n    }\n    finally {\n        this.deferredImportSelectors = new ArrayList&lt;&gt;();\n    }\n}\n\npublic void processGroupImports() {\n    for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {\n        Predicate&lt;String&gt; exclusionFilter = grouping.getCandidateFilter();\n        grouping.getImports().forEach(entry -&gt; {\n            ConfigurationClass configurationClass = this.configurationClasses.get(entry.getMetadata());\n            try {\n                processImports(configurationClass, asSourceClass(configurationClass, exclusionFilter),\n                        Collections.singleton(asSourceClass(entry.getImportClassName(), exclusionFilter)),\n                        exclusionFilter, false);\n            }\n            catch (BeanDefinitionStoreException ex) {\n                throw ex;\n            }\n            catch (Throwable ex) {\n                throw new BeanDefinitionStoreException(\n                        \"Failed to process import candidates for configuration class &#91;\" +\n                                configurationClass.getMetadata().getClassName() + \"]\", ex);\n            }\n        });\n    }\n}\n\n\/**\n * \u8fd4\u56de\u7ec4\u5b9a\u4e49\u7684\u5bfc\u5165\u3002\n * @return \u6bcf\u4e2a\u5bfc\u5165\u53ca\u5176\u5173\u8054\u7684\u914d\u7f6e\u7c7b\n *\/\npublic Iterable&lt;Group.Entry&gt; getImports() {\n    for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {\n        this.group.process(deferredImport.getConfigurationClass().getMetadata(),\n                deferredImport.getImportSelector());\n    }\n    return this.group.selectImports();\n}\n\npublic DeferredImportSelector getImportSelector() {\n    return this.importSelector;\n}\n\n\/\/ org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup#process\n@Override\npublic void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {\n    Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector,\n            () -&gt; String.format(\"Only %s implementations are supported, got %s\",\n                    AutoConfigurationImportSelector.class.getSimpleName(),\n                    deferredImportSelector.getClass().getName()));\n    AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)\n            .getAutoConfigurationEntry(annotationMetadata);\n    this.autoConfigurationEntries.add(autoConfigurationEntry);\n    for (String importClassName : autoConfigurationEntry.getConfigurations()) {\n        this.entries.putIfAbsent(importClassName, annotationMetadata);\n    }\n}<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"15\" src=\"blob:http:\/\/42.194.186.76:8000\/985bb28d-bd45-4dde-b3dc-e40ef69dbef3\" width=\"15\"> \u200b<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u200b &nbsp;1\u3001\u5728Spring Boot\u7684\u542f\u52a8\u8fc7\u7a0b\u4e2d\uff0c\u8981\u8fd0\u884cSpring\u5e94\u7528\u7a0b\u5e8f\uff0c\u521b\u5efa\u5e76\u5237\u65b0\u4e00\u4e2a\u65b0\u7684App &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/www.fallsky.top\/?p=48\" class=\"more-link\">\u7ee7\u7eed\u9605\u8bfb<span class=\"screen-reader-text\">\u201cSpring Boot\u81ea\u52a8\u914d\u7f6e\u539f\u7406\u201d<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-48","post","type-post","status-publish","format-standard","hentry","category-uncategorized","entry"],"_links":{"self":[{"href":"http:\/\/www.fallsky.top\/index.php?rest_route=\/wp\/v2\/posts\/48"}],"collection":[{"href":"http:\/\/www.fallsky.top\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.fallsky.top\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.fallsky.top\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.fallsky.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=48"}],"version-history":[{"count":1,"href":"http:\/\/www.fallsky.top\/index.php?rest_route=\/wp\/v2\/posts\/48\/revisions"}],"predecessor-version":[{"id":49,"href":"http:\/\/www.fallsky.top\/index.php?rest_route=\/wp\/v2\/posts\/48\/revisions\/49"}],"wp:attachment":[{"href":"http:\/\/www.fallsky.top\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=48"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.fallsky.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=48"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.fallsky.top\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=48"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}