<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Spring on 小蜜蜂</title>
        <link>https://xumf.net/tags/spring/</link>
        <description>Recent content in Spring on 小蜜蜂</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh</language>
        <lastBuildDate>Thu, 30 Jan 2025 22:39:17 +0800</lastBuildDate><atom:link href="https://xumf.net/tags/spring/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>Spring 三级缓存</title>
            <link>https://xumf.net/blog/springthridlevelcache/</link>
            <pubDate>Thu, 30 Jan 2025 22:39:17 +0800</pubDate>
            <guid>https://xumf.net/blog/springthridlevelcache/</guid>
            <description>&lt;h2 id=&#34;三级缓存&#34;&gt;三级缓存&#xA;&lt;/h2&gt;&lt;p&gt;在 Spring 框架中，&lt;strong&gt;三级缓存&lt;/strong&gt;机制用于解决单例 Bean 的循环依赖问题。当两个或多个单例 Bean 相互依赖时，Spring 通过三级缓存来确保它们能够相互引用，避免了循环依赖倒置的错误。&lt;/p&gt;&#xA;&lt;h3 id=&#34;三级缓存的组成&#34;&gt;三级缓存的组成：&#xA;&lt;/h3&gt;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;Spring的DefaultSingletonBeanRegistry类三级缓存对象&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;final&lt;/span&gt; Map&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;String, Object&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; singletonObjects &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; ConcurrentHashMap&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt;(256);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;final&lt;/span&gt; Map&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;String, Object&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; earlySingletonObjects &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; ConcurrentHashMap&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt;(16);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;final&lt;/span&gt; Map&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;String, ObjectFactory&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; singletonFactories &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; HashMap&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt;(16);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;一级缓存（&lt;strong&gt;&lt;strong&gt;singletonObjects&lt;/strong&gt;&lt;/strong&gt;）&lt;/strong&gt;：存放完全初始化的单例 Bean 实例。当请求一个 Bean 时，Spring 首先从一级缓存中查找，如果存在，则直接返回实例。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;二级缓存（&lt;strong&gt;&lt;strong&gt;earlySingletonObjects&lt;/strong&gt;&lt;/strong&gt;）&lt;/strong&gt;：存放尚未完全初始化的单例 Bean 实例，通常是指构造函数已执行完毕，但属性尚未填充的 Bean。当 Bean 的构造函数执行完毕后，但属性尚未填充的 Bean。当 Bean 的构造函数执行完毕后，Spring 会将其放入二级缓存中，以便在依赖注入过程中，其它 Bean 可以获取该 Bean 的早期引用，从而解决循环依赖。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;三级缓存（&lt;strong&gt;&lt;strong&gt;singletonFactories&lt;/strong&gt;&lt;/strong&gt;）&lt;/strong&gt;：存放用于创建单例 Bean 的工厂对象（ObjectFactory）。当 Bean 正在创建过程中，且需要提前暴露其引用时，Spring 会将用于创建该 Bean 的工厂对象放入三级缓存中。其它 Bean 在依赖注入时，可以通过三级缓存获取该工厂对象，从而获取正在创建中的 Bean 的引用。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;三级缓存解决下循环依赖的流程&#34;&gt;三级缓存解决下循环依赖的流程&#xA;&lt;/h3&gt;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;实例化 Bean&lt;/strong&gt;：当 Spring 需要创建一个 Bean 时，首先会检查一级缓存中是否已有该 Bean 的实例。如果没有，则开始实例化该 Bean。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;放入三级缓存&lt;/strong&gt;：在实例化过程中，Spring 会将用于创建该 Bean 的工厂对象放入三级缓存中。这样，其它 Bean 在依赖注入时，可以通过三级缓存获取该工厂对象，从而获取到正在创建中的 Bean 的引用。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;放入二级缓存&lt;/strong&gt;：当 Bean 的构造函数执行完毕后，Spring 会将其放入二级缓存中。此时，其它 Bean 可以从二级缓存中获取到该 Bean 的早期引用。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;放入一级缓存&lt;/strong&gt;：当 Bean 的属性填充和初始化方法执行完毕后，Spring 会将其放入一级缓存，表示该 Bean 已完全初始化。此时，其它 Bean 可以从一级缓存中获取到该 Bean 的实例。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;为什么需要三级缓存&#34;&gt;为什么需要三级缓存？&#xA;&lt;/h3&gt;&lt;p&gt;虽然二级缓存可以解决大部分循环依赖问题，但在涉及 AOP（面向切面编程）时，三级缓存显得尤为重要。在 AOP 代理的情况下，Bean 的创建过程需要通过代理工厂来生成代理对象。三级缓存缓存中的工厂对象正是用于创建这些代理对象的。如果没有三级缓存，Spring 将无法在 Bean 创建过程中提前暴露代理对象，从而导致循环依赖无法解决。&lt;/p&gt;&#xA;&lt;p&gt;通过引用三级缓存，Spring 能够在 Bean 创建过程中提前暴露代理对象，确保循环依赖能够正确解决。这使得 Spring 在处理复杂的依赖关系时，能够保持高效和灵活。&lt;/p&gt;&#xA;&lt;p&gt;总之，Spring 的三级缓存机制通过合理的缓存策略，确保了单例 Bean 在存在循环依赖和 AOP 代理的情况下，能够正确地相互引用，避免了循环依赖导致的错误。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>SpringBoot 启动流程</title>
            <link>https://xumf.net/blog/springbootstartflow/</link>
            <pubDate>Tue, 09 May 2023 23:36:22 +0800</pubDate>
            <guid>https://xumf.net/blog/springbootstartflow/</guid>
            <description>&lt;p&gt;Spring Boot 的启动入口是 &lt;code&gt;SpringApplication.run()&lt;/code&gt;，其核心流程可概括为三个阶段：&lt;strong&gt;准备阶段 → 刷新上下文 → 启动完成后的回调&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;h2 id=&#34;一整体启动流程&#34;&gt;一、整体启动流程&#xA;&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1. SpringApplication.run() 入口&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2. 准备阶段：&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├─ 推断应用类型（Reactive / Servlet）&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├─ 加载所有 SpringApplicationRunListener&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├─ 构建并准备 Environment（解析 application.yml/properties）&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   └─ 打印 Banner&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3. 创建并准备 ApplicationContext：&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├─ 创建上下文实例（AnnotationConfigServletWebServerApplicationContext）&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├─ 执行 ApplicationContextInitializer&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├─ 注册启动参数中的主配置类（@SpringBootApplication 标注的类）&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   └─ 调用 refresh() 方法 → 进入 Spring 容器核心流程&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4. 刷新后回调：&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├─ 执行 CommandLineRunner / ApplicationRunner&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   └─ 启动内嵌 Web 容器（Tomcat / Jetty / Undertow）&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;refresh()&lt;/code&gt; 方法是 Spring 容器初始化的核心，由 &lt;code&gt;AbstractApplicationContext.refresh()&lt;/code&gt; 定义，其中 13 个步骤依次执行。&lt;/p&gt;&#xA;&lt;h2 id=&#34;二refresh-核心步骤&#34;&gt;二、refresh() 核心步骤&#xA;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;refresh()&lt;/code&gt; 中的关键步骤（按顺序）：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;prepareRefresh()&lt;/strong&gt;：设置容器状态，初始化属性源和早期事件发布器&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;obtainFreshBeanFactory()&lt;/strong&gt;：刷新 BeanFactory，解析 Bean 定义（从配置类、XML、@ComponentScan 扫描结果）&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;prepareBeanFactory()&lt;/strong&gt;：配置 BeanFactory 的类加载器、SpEL 解析器、属性编辑器，注册 Aware 接口回调需要的 Bean&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;postProcessBeanFactory()&lt;/strong&gt;：子类扩展点（Web 容器在此注册 ServletContextAware 处理器）&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;invokeBeanFactoryPostProcessors()&lt;/strong&gt;：调用所有 BeanFactoryPostProcessor。最关键的是 &lt;strong&gt;ConfigurationClassPostProcessor&lt;/strong&gt;，它解析 @Configuration、@ComponentScan、@Import、@Bean 并注册所有 Bean 定义&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;registerBeanPostProcessors()&lt;/strong&gt;：注册 BeanPostProcessor。此时只注册不执行——真正执行时机在 bean 实例化阶段触发&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;initMessageSource()&lt;/strong&gt;：初始化国际化组件&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;initApplicationEventMulticaster()&lt;/strong&gt;：初始化事件广播器&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;onRefresh()&lt;/strong&gt;：创建并启动内嵌 Web 容器（Tomcat 在此启动）&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;registerListeners()&lt;/strong&gt;：注册所有的 ApplicationListener&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;finishBeanFactoryInitialization()&lt;/strong&gt;：实例化所有非懒加载的单例 Bean——这是&lt;strong&gt;启动最耗时&lt;/strong&gt;的阶段&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;finishRefresh()&lt;/strong&gt;：发布 ContextRefreshedEvent 事件&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;三核心-beanpostprocessor-详解&#34;&gt;三、核心 BeanPostProcessor 详解&#xA;&lt;/h2&gt;&lt;p&gt;BeanPostProcessor 在 bean 实例化过程的两个时机触发：&lt;strong&gt;初始化前（BeforeInitialization）&lt;/strong&gt; 和 &lt;strong&gt;初始化后（AfterInitialization）&lt;/strong&gt;。下面列出 Spring Boot 自动装配中最常用的几个：&lt;/p&gt;&#xA;&lt;h3 id=&#34;依赖注入相关&#34;&gt;依赖注入相关&#xA;&lt;/h3&gt;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;AutowiredAnnotationBeanPostProcessor&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;处理 @Autowired、@Value、@Inject&lt;/li&gt;&#xA;&lt;li&gt;postProcessBeforeInitialization：解析注入点并注入依赖&lt;/li&gt;&#xA;&lt;li&gt;源码：&lt;code&gt;org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;CommonAnnotationBeanPostProcessor&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;处理 JSR-250 注解：@Resource、@PostConstruct、@PreDestroy&lt;/li&gt;&#xA;&lt;li&gt;@Resource 按名称优先注入，与 @Autowired 的 Type 优先策略不同——混用时注意&lt;/li&gt;&#xA;&lt;li&gt;源码：&lt;code&gt;org.springframework.context.annotation.CommonAnnotationBeanPostProcessor&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;生命周期回调相关&#34;&gt;生命周期回调相关&#xA;&lt;/h3&gt;&lt;ol start=&#34;3&#34;&gt;&#xA;&lt;li&gt;&lt;strong&gt;InitDestroyAnnotationBeanPostProcessor&lt;/strong&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;处理 @PostConstruct 和 @PreDestroy&lt;/li&gt;&#xA;&lt;li&gt;与 CommonAnnotationBeanPostProcessor 的职责有重叠——InitDestroyAnnotationBeanPostProcessor 更底层，CommonAnnotationBeanPostProcessor 扩展了对 @Resource 的支持&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;aware-接口注入&#34;&gt;Aware 接口注入&#xA;&lt;/h3&gt;&lt;ol start=&#34;4&#34;&gt;&#xA;&lt;li&gt;&lt;strong&gt;ApplicationContextAwareProcessor&lt;/strong&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;处理 ApplicationContextAware、EnvironmentAware、ResourceLoaderAware 等&lt;/li&gt;&#xA;&lt;li&gt;postProcessBeforeInitialization 阶段注入，早于 @Autowired&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;占位符解析&#34;&gt;占位符解析&#xA;&lt;/h3&gt;&lt;ol start=&#34;5&#34;&gt;&#xA;&lt;li&gt;&lt;strong&gt;EmbeddedValueResolverAwareBeanPostProcessor&lt;/strong&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;处理 EmbeddedValueResolverAware 接口，注入 StringValueResolver&lt;/li&gt;&#xA;&lt;li&gt;用于解析 &lt;code&gt;${property}&lt;/code&gt; 占位符和 &lt;code&gt;#{spEL}&lt;/code&gt; 表达式&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;aop-代理&#34;&gt;AOP 代理&#xA;&lt;/h3&gt;&lt;ol start=&#34;6&#34;&gt;&#xA;&lt;li&gt;&lt;strong&gt;InfrastructureAdvisorAutoProxyCreator&lt;/strong&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;为符合条件的 Bean 生成 AOP 代理&lt;/li&gt;&#xA;&lt;li&gt;postProcessAfterInitialization 阶段触发：先有 Bean 实例，再通过代理增加切面逻辑&lt;/li&gt;&#xA;&lt;li&gt;源码：&lt;code&gt;org.springframework.aop.framework.autoproxy. InfrastructureAdvisorAutoProxyCreator&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;异常转换&#34;&gt;异常转换&#xA;&lt;/h3&gt;&lt;ol start=&#34;7&#34;&gt;&#xA;&lt;li&gt;&lt;strong&gt;PersistenceExceptionTranslationPostProcessor&lt;/strong&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;将持久化层异常（JPA、Hibernate）转换为 Spring DataAccessException&lt;/li&gt;&#xA;&lt;li&gt;通常提前注册 BeanPostProcessor 以处理所有持久化 Bean&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;事件与注解驱动&#34;&gt;事件与注解驱动&#xA;&lt;/h3&gt;&lt;ol start=&#34;8&#34;&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;EventListenerMethodProcessor&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;处理 @EventListener，注册事件监听方法&lt;/li&gt;&#xA;&lt;li&gt;源码：&lt;code&gt;org.springframework.context.event.EventListenerMethodProcessor&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;ScheduledAnnotationBeanPostProcessor&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;处理 @Scheduled，注册定时任务&lt;/li&gt;&#xA;&lt;li&gt;与 @Async 由不同处理器管理：@Async 由 AsyncAnnotationBeanPostProcessor 处理&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;import-扩展&#34;&gt;Import 扩展&#xA;&lt;/h3&gt;&lt;ol start=&#34;10&#34;&gt;&#xA;&lt;li&gt;&lt;strong&gt;ImportAwareBeanPostProcessor&lt;/strong&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;处理 @Import 导入的类中实现 ImportAware 接口的 Bean&lt;/li&gt;&#xA;&lt;li&gt;postProcessBeforeInitialization 阶段注入导入元数据&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;四beanfactorypostprocessor&#34;&gt;四、BeanFactoryPostProcessor&#xA;&lt;/h2&gt;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;ConfigurationClassPostProcessor&lt;/strong&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;最重要的 BeanFactoryPostProcessor&lt;/strong&gt;，负责解析 @Configuration 类&lt;/li&gt;&#xA;&lt;li&gt;处理 @ComponentScan（包扫描）、@Import（导入配置类）、@Bean（方法级别 Bean 定义）&lt;/li&gt;&#xA;&lt;li&gt;在 invokeBeanFactoryPostProcessors() 阶段执行——比任何 BeanPostProcessor 都早&lt;/li&gt;&#xA;&lt;li&gt;没有它，所有注解配置的 Bean 都不会被注册&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;五常见问题排查&#34;&gt;五、常见问题排查&#xA;&lt;/h2&gt;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;启动慢怎么办？&lt;/strong&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;排查点：finishBeanFactoryInitialization 阶段耗时最长，检查是否有大量懒加载泄漏、@ComponentScan 覆盖过多包路径&lt;/li&gt;&#xA;&lt;li&gt;启用 lazy-initialization（&lt;code&gt;spring.main.lazy-initialization=true&lt;/code&gt;）可加速启动，但注意首次请求变慢&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Bean 初始化异常如何排查？&lt;/strong&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;开启 &lt;code&gt;debug=true&lt;/code&gt; 查看 ConditionEvaluationReport（自动配置条件评估报告）&lt;/li&gt;&#xA;&lt;li&gt;关键日志关键词：&lt;code&gt;UnsatisfiedDependencyException&lt;/code&gt;、&lt;code&gt;BeanCreationException&lt;/code&gt;、&lt;code&gt;NoSuchBeanDefinitionException&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;AOP 代理不生效？&lt;/strong&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;检查类是否被 final 修饰（CGLIB 无法代理 final 类）&lt;/li&gt;&#xA;&lt;li&gt;检查同一个类内部方法调用 AOP 代理问题（自调用不走代理）&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;@PostConstruct 与 afterPropertiesSet 的执行顺序？&lt;/strong&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;InitializingBean.afterPropertiesSet()&lt;/code&gt; → &lt;code&gt;@PostConstruct&lt;/code&gt; → 自定义 &lt;code&gt;init-method&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;顺序：InitializingBean → BeanPostProcessor.postProcessBeforeInitialization → @PostConstruct → afterPropertiesSet → init-method → BeanPostProcessor.postProcessAfterInitialization&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;ConfigurationClassPostProcessor 的常见错误&lt;/strong&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;@ComponentScan 未生效：检查启动类的位置是否在根包&lt;/li&gt;&#xA;&lt;li&gt;@Bean 方法被 final 修饰：CGLIB 无法重写 final 方法&lt;/li&gt;&#xA;&lt;li&gt;@Import 导入的配置类重复：Spring 5.2+ 支持 @Import 去重，但注意 @Import 和 @ComponentScan 同时扫描到同一个类会导致重复注册&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;</description>
        </item></channel>
</rss>
