BeanFactory与ApplicationContext的协作机制

149 阅读35分钟

一、Spring容器架构分层详解

1.1 核心接口继承体系

image.png

关键接口说明​:

  • BeanFactory​:基础容器接口,定义getBean()containsBean()等核心方法
  • ListableBeanFactory​:扩展查询能力,支持getBeanNamesForType()
  • HierarchicalBeanFactory​:支持父子容器层级结构
  • ApplicationContext​:企业级容器,继承自ListableBeanFactoryMessageSource

二、BeanFactory实现原理深度剖析

2.1 单例缓存管理机制

通过反射获取DefaultSingletonBeanRegistrysingletonObjects字段:

Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
singletonObjects.setAccessible(true);
ConcurrentHashMap<String, Object> singletonMap = (ConcurrentHashMap) singletonObjects.get(beanFactory);

缓存结构源码分析​:

// DefaultSingletonBeanRegistry.java
protected final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isFactoryBean(beanName)) {
        synchronized (this.singletonObjects) {
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null) {
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject;
}

2.2 BeanDefinition加载流程

完整加载时序图​:

[BeanFactoryPostProcessor] 
  → [BeanDefinitionLoader] 
    → [XmlBeanDefinitionReader] 
      → [DefaultBeanDefinitionDocumentReader] 
        → [BeanDefinitionParserDelegate]

关键处理步骤​:

  1. 资源定位:通过ResourceLoader加载配置文件
  2. 文档解析:使用BeanDefinitionParser解析XML/YAML
  3. 定义注册:将解析结果存入BeanDefinitionRegistry

三、ApplicationContext高级特性详解

3.1 事件驱动模型全流程

事件传播时序图​:

[ApplicationEventPublisher] 
  → [ApplicationEventMulticaster] 
    → [SimpleApplicationEventMulticaster]
      → [ApplicationListener]

异步事件处理配置​:

package com.dwl.application_context_case.config;

import com.dwl.application_context_case.event.MyMonitor;
import com.dwl.application_context_case.processor.MyBeanFactoryPostProcessor;
import com.dwl.application_context_case.service.ProdAuditService;
import com.dwl.log.Logger;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import javax.sql.DataSource;
import java.util.Map;
import java.util.concurrent.Executor;

/**
 * @ClassName MyBean
 * @Description <h2>应用配置中心</h2>
 * <p>
 * <b>核心功能:</b>
 * <ul>
 *   <li>数据源配置</li>
 *   <li>异步线程池管理</li>
 *   <li>环境感知的Bean注册</li>
 *   <li>多租户数据源路由</li>
 * </ul>
 * </p>
 *
 * <p>
 * <b>配置加载顺序:</b>
 * <ol>
 *   <li>通过 {@link #dataSource()} 加载数据源配置</li>
 *   <li>通过 {@link #asyncExecutor()} 初始化线程池</li>
 *   <li>根据 Profile 注册条件化 Bean</li>
 *   <li>通过 {@link #beanFactoryPostProcessor()} 动态注册生产环境 Bean</li>
 * </ol>
 * </p>
 * @Version 1.0.0
 * @Date 2025
 * @Author By Dwl
 */
@Configuration
@ComponentScan(basePackages = "com.dwl.application_context_case.service")
@EnableAsync
@Data
@NoArgsConstructor // 添加无参构造器供CGLIB代理使用
public class AppConfig {

    /**
     * Spring环境对象(必须通过构造器注入)
     */
    private Environment env;

    /**
     * <h3>构造器注入 Environment</h3>
     * <p>
     * 使用构造器注入确保 Spring 在创建代理时能正确完成依赖注入<br>
     * 注意:Lombok 的 {@code @NoArgsConstructor} 已移除以避免代理问题
     * </p>
     *
     * @param env Spring 环境对象(通过 {@link org.springframework.context.annotation.Configuration} 自动注入)
     */
    @Autowired
    public AppConfig(Environment env) {
        this.env = env;
        Logger.infoF("AppConfig initialized with environment: {}", env.getProperty("spring.profiles.active"));
    }


    /**
     * <h3>数据源配置</h3>
     * <p>
     * 使用 HikariCP 连接池,参数从环境变量读取<br>
     * 示例配置(application-prod.properties):
     * <pre>
     * spring.datasource.url=jdbc:mysql://prod-db:3306/mdb
     * spring.datasource.username=prod_user
     * spring.datasource.password=prod_password
     * </pre>
     * </p>
     */
    @Bean
    public DataSource dataSource() {
        Logger.debug("Initializing DataSource...");
//        HikariDataSource dataSource = new HikariDataSource();
//        dataSource.setJdbcUrl(env.getProperty("spring.datasource.url"));
//        dataSource.setUsername(env.getProperty("spring.datasource.username"));
//        dataSource.setPassword(env.getProperty("spring.datasource.password"));
//
//        // 连接池配置
//        dataSource.setMaximumPoolSize(20);
//        dataSource.setMinimumIdle(5);
//        dataSource.setIdleTimeout(30000);
        Logger.info("DataSource configured successfully");
        return null;
    }

    /**
     * <h3>异步线程池配置</h3>
     * <p>
     * 核心参数:
     * <ul>
     *   <li>corePoolSize: 5(最小工作线程数)</li>
     *   <li>maxPoolSize: 20(最大并发线程数)</li>
     *   <li>queueCapacity: 100(任务队列容量)</li>
     * </ul>
     * </p>
     */
    @Bean(name = "asyncExecutor")
    public Executor asyncExecutor() {
        Logger.debug("Configuring async executor...");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("Async-");
        executor.initialize();
        Logger.infoF("Async executor [{}] initialized", executor.getThreadNamePrefix());
        return executor;
    }

    /**
     * <h3>环境感知的监听器注册</h3>
     * <p>
     * 仅在开发环境 ({@code dev} Profile) 注册调试监听器<br>
     * 使用 {@link Profile} 注解实现条件化 Bean 注册
     * </p>
     */
    @Bean
    @Profile("dev")
    public MyMonitor devEventMonitor() {
        Logger.info("Registering dev environment monitor");
        return new MyMonitor(true); // 启用调试模式
    }

    /**
     * <h3>Bean工厂后处理器</h3>
     * <p>
     * 动态注册生产环境专用 Bean<br>
     * 通过实现 {@link EnvironmentAware} 直接获取环境变量
     * </p>
     */
    @Bean
    public MyBeanFactoryPostProcessor beanFactoryPostProcessor() {
        return new MyBeanFactoryPostProcessorImpl();
    }

    /**
     * <h4>Bean工厂后处理器实现</h4>
     * <p>
     * 通过 {@link EnvironmentAware} 获取环境变量,避免构造器注入问题<br>
     * 仅在激活 {@code prod} Profile 时注册审计服务
     * </p>
     */
    private static class MyBeanFactoryPostProcessorImpl extends MyBeanFactoryPostProcessor implements EnvironmentAware {
        private Environment env;

        @Override
        public void setEnvironment(@NonNull Environment environment) {
            this.env = environment;
            Logger.debug("Environment set in MyBeanFactoryPostProcessorImpl");
        }

        @Override
        public void postProcessBeanFactory(@NonNull ConfigurableListableBeanFactory factory) {
            super.postProcessBeanFactory(factory);
            if (env.acceptsProfiles(Profiles.of("prod"))) {
                Logger.info("Activating production profile - registering ProdAuditService");
                registerProductionBeans(factory);
            }
        }

        private void registerProductionBeans(ConfigurableListableBeanFactory factory) {
            GenericBeanDefinition auditDef = new GenericBeanDefinition();
            auditDef.setBeanClass(ProdAuditService.class);
            ((BeanDefinitionRegistry) factory).registerBeanDefinition("auditService", auditDef);
            Logger.info("ProdAuditService registered successfully");
        }
    }

    /**
     * <h3>多租户数据源配置</h3>
     * <p>
     * 通过 {@link ConfigurationProperties} 绑定配置前缀<br>
     * 示例配置(application.yml):
     * <pre>
     * spring:
     *   tenant:
     *     defaultSchema: public
     *     schemaMappings:
     *       tenant1: schema1
     *       tenant2: schema2
     * </pre>
     * </p>
     */
    @Bean
    @ConfigurationProperties(prefix = "spring.tenant")
    public TenantConfig tenantConfig() {
        return new TenantConfig();
    }

    @Data
    public static class TenantConfig {
        /**
         * 默认数据库 Schema
         */
        private String defaultSchema;

        /**
         * 租户ID到Schema的映射关系
         */
        private Map<String, String> schemaMappings;
    }

}

package com.dwl.application_context_case.config;

import com.dwl.application_context_case.event.MyRegisteredEvent;
import com.dwl.log.Logger;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
 * 异步事件监听器组件
 * <p>
 * 该类用于异步处理应用程序中发布的特定事件,通过Spring的事件监听机制与异步执行结合,
 * 实现非阻塞的业务逻辑处理。适用于需要解耦且耗时较长的操作场景(如发送通知、日志记录等)。
 * </p>
 *
 * <p>
 * 主要功能:
 * 1. 监听 {@link MyRegisteredEvent} 用户注册成功事件
 * 2. 使用异步线程池处理事件回调
 * 3. 实现业务逻辑的解耦和非阻塞执行
 * 4. 记录完整的事件处理日志(包括正常流程和异常情况)
 * </p>
 *
 * @author By Dwl
 * @version 1.0.0
 * @see org.springframework.context.event.EventListener
 * @see org.springframework.scheduling.annotation.Async
 * @since 2025
 */
@Component
public class AsyncEventListener {

    private static final String EVENT_SUCCESS = "Event processed successfully";
    private static final String EVENT_FAIL = "Event processing failed";

    /**
     * 异步处理用户注册成功事件
     * <p>
     * 当系统中发布{@link MyRegisteredEvent}事件时,此方法会被触发执行。
     * 方法使用指定的异步线程池执行,避免阻塞主线程。
     * </p>
     *
     * <p>
     * 日志记录策略:
     * 1. 方法入口:记录事件接收信息(INFO级别)
     * 2. 业务处理:记录关键业务参数(DEBUG级别)
     * 3. 成功退出:记录处理结果(INFO级别)
     * 4. 异常捕获:记录完整错误堆栈(ERROR级别)
     * </p>
     *
     * @param event 用户注册事件对象,包含注册相关的业务数据
     *              <ul>
     *                  <li>userId: 新注册用户的唯一标识</li>
     *                  <li>userName: 用户名称</li>
     *                  <li>registerTime: 注册时间戳</li>
     *              </ul>
     * @see MyRegisteredEvent 事件对象定义
     * @see org.springframework.scheduling.annotation.Async 异步执行注解
     * @see org.springframework.context.event.EventListener 事件监听注解
     */
    @Async("asyncExecutor")  // 使用名为"eventExecutor"的自定义线程池
    @EventListener        // 标记为事件监听方法
    public void handleAsyncEvent(MyRegisteredEvent event) {
        // 记录事件接收日志(包含事件关键信息)
        Logger.infoF("Received async event - User Registration: {}", event);

        try {
            // 业务参数记录(DEBUG级别,生产环境可关闭)
            // Logger.debug("Processing event with parameters - userId: {}, userName: {}, registerTime: {}",
            //        event.getUserId(), event.getUserName(), event.getRegisterTime());

            // 1. 获取事件携带的业务数据
            // Long userId = event.getUserId();
            // String userName = event.getUserName();

            // 2. 执行实际业务操作(示例伪代码)
            // sendWelcomeEmail(userId, userName);
            // logRegistrationEvent(event);

            // 模拟业务处理
            Thread.sleep(1000);  // 模拟耗时操作

            // 记录成功日志(带业务标识)
            // Logger.infoF("{} - User {} registration processed successfully", EVENT_SUCCESS, userId);

        } catch (InterruptedException e) {
            // 记录中断异常(保留原始堆栈)
            Thread.currentThread().interrupt();  // 重置中断状态
            // Logger.errorF("{} failed for event [{}] - Error: {}", EVENT_FAIL, event.getId(), e.getMessage(), e);

        } catch (Exception e) {
            // 记录业务处理异常(带事件标识)
            Logger.errorF("{} failed for event - Error: {}",
                    EVENT_FAIL, e.getMessage());

            // 可根据需要在此处添加:
            // 1. 异常分类处理
            // 2. 重试机制
            // 3. 死信队列投递
        }
    }
}

3.2 资源加载策略对比

加载方式语法示例适用场景特点
精确加载classpath:app.yml明确知道资源位置严格匹配单个文件
通配符加载classpath*:*.xml加载所有匹配资源支持Ant风格路径匹配
文件系统加载file:/data/config.xml加载绝对路径资源需要文件系统访问权限
类路径资源加载classpath:META-INF/*.xml加载类路径下所有匹配资源自动识别打包方式

四、容器生命周期完整流程

4.1 启动阶段时序图

SpringApplication.run()
  → refreshContext()
    → AbstractApplicationContext.refresh()
      → AbstractApplicationContext.invokeBeanFactoryPostProcessors()
        → postProcessBeanFactory()
          → MyBeanFactoryPostProcessor.postProcessBeanFactory()
            → 修改Bean定义
      → finishBeanFactoryInitialization()
        → getBean()
          → doGetBean()
            → doGetBeanFromSingletons()
              → getSingleton()
                → createBean()
                  → doCreateBean()
                    → populateBean()
                      → initializeBean()
                        → @PostConstruct
                        → InitializingBean.afterPropertiesSet()

4.2 Bean生命周期扩展点

package com.dwl.application_context_case.service;

import com.dwl.log.Logger;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.NonNull;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.stereotype.Component;

/**
 * 生命周期管理示例Bean
 * <p>
 * 该类演示Spring容器的完整Bean生命周期管理,包含:
 * 1. Bean元数据感知能力(名称/工厂)
 * 2. JSR-250标准生命周期方法
 * 3. Spring原生生命周期接口
 * 4. 初始化/销毁回调组合使用
 * </p>
 *
 * <p>
 * 生命周期执行顺序(简化版):
 * 1. setBeanName()
 * 2. setBeanFactory()
 * 3. @PostConstruct
 * 4. afterPropertiesSet()
 * 5. 自定义init-method
 * 6. @PreDestroy
 * 7. destroy()
 * </p>
 *
 * <p>
 * 日志策略:
 * - INFO级别:记录关键生命周期节点
 * - DEBUG级别:记录调试信息
 * - WARN级别:记录潜在问题
 * - ERROR级别:记录初始化失败
 * </p>
 *
 * @author By Dwl
 * @version 1.0.0
 * @see BeanNameAware
 * @see BeanFactoryAware
 * @see InitializingBean
 * @see DisposableBean
 * @since 2025
 */
@Component
public class LifecycleBean implements BeanNameAware, BeanFactoryAware,
        InitializingBean, DisposableBean {

    private String beanName;

    /**
     * 设置Bean名称
     * <p>
     * 生命周期阶段:实例化后立即执行
     * 执行顺序:优先于其他初始化方法
     * </p>
     *
     * @param name Spring容器分配的Bean名称
     */
    @Override
    public void setBeanName(@NonNull String name) {
        this.beanName = name;
        Logger.infoF("Bean名称已设置 - Name: {}, Class: {}", name, this.getClass().getSimpleName());
    }

    /**
     * 设置BeanFactory引用
     * <p>
     * 生命周期阶段:实例化后立即执行
     * 执行顺序:紧随setBeanName()
     * </p>
     *
     * @param factory 当前Bean所属的BeanFactory实例
     * @throws BeansException 如果设置失败
     */
    @Override
    public void setBeanFactory(BeanFactory factory) {
        Logger.debugF("BeanFactory引用已设置 - Factory ID: {}", factory.toString());
    }

    /**
     * JSR-250标准初始化方法
     * <p>
     * 生命周期阶段:属性设置完成后执行
     * 执行顺序:在afterPropertiesSet()之后
     * </p>
     *
     * @throws Exception 初始化失败时抛出异常
     * @see PostConstruct
     */
    @PostConstruct
    public void init() throws Exception {
        Logger.info("JSR-250初始化方法执行 - 开始");
        // 模拟初始化操作
        validateRequiredProperties();
        Logger.info("JSR-250初始化方法执行 - 完成");
    }

    /**
     * Spring原生初始化方法
     * <p>
     * 生命周期阶段:所有属性设置完成后执行
     * 执行顺序:在@PostConstruct之后
     * </p>
     */
    @Override
    public void afterPropertiesSet() {
        Logger.info("Spring初始化方法执行 - 开始");
        // 执行自定义初始化逻辑
        initializeResources();
        Logger.info("Spring初始化方法执行 - 完成");
    }

    /**
     * JSR-250标准销毁方法
     * <p>
     * 生命周期阶段:容器销毁前执行
     * 执行顺序:在destroy()之前
     * </p>
     *
     * @see PreDestroy
     */
    @PreDestroy
    public void destroyJsr250() {
        Logger.warn("JSR-250销毁方法执行 - 开始");
        cleanupResources();
        Logger.warn("JSR-250销毁方法执行 - 完成");
    }

    /**
     * Spring原生销毁方法
     * <p>
     * 生命周期阶段:容器销毁时最后执行
     * 执行顺序:在@PreDestroy之后
     * </p>
     */
    @Override
    public void destroy() {
        // 实际应选择一种实现方式,此处保留错误提示
        Logger.error("检测到重复的destroy方法定义!请保留其中一个实现");
    }

    // ----------------------
    // 内部辅助方法
    // ----------------------

    private void validateRequiredProperties() {
        // 实际应验证必要属性是否已设置
        if (beanName == null) {
            throw new IllegalStateException("Bean名称未正确设置");
        }
    }

    private void initializeResources() {
        // 实际应执行资源初始化操作
        Logger.debugF("正在初始化资源 - Bean名称: {}", beanName);
    }

    private void cleanupResources() {
        // 实际应执行资源清理操作
        Logger.debugF("正在清理资源 - Bean名称: {}", beanName);
    }
}

五、高级调试技巧与最佳实践

5.1 容器状态诊断

package com.dwl.application_context_case;

import com.dwl.application_context_case.event.MyRegisteredEvent;
import com.dwl.application_context_case.service.MyBean;
import com.dwl.log.Logger;
import com.dwl.util.ObjectUtil;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Locale;
import java.util.Map;

/**
 * @ClassName BeanFactoryAndApplicationContext
 * @Description 深入探究Spring框架中BeanFactory与ApplicationContext的核心差异及协作关系
 * 通过实例演示Spring容器核心接口的使用方法,包括Bean生命周期管理、资源加载、事件发布等特性
 * @Version 1.0.0
 * @Date 2025
 * @Author By Dwl
 */
@SpringBootApplication
public class BeanFactoryAndApplicationContext {

    /**
     * 应用程序入口方法,演示Spring容器核心功能
     *
     * @param args 启动参数
     * @throws NoSuchFieldException   当访问不存在的字段时抛出
     * @throws IllegalAccessException 当字段访问权限不足时抛出
     * @throws IOException            当资源加载失败时抛出
     */
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {
        // 1. 初始化Spring应用上下文(ConfigurableApplicationContext是ApplicationContext的子接口)
        //    提供配置管理能力,支持运行时修改Bean定义和刷新上下文
        ConfigurableApplicationContext context = SpringApplication.run(BeanFactoryAndApplicationContext.class, args);

        /*
         * 2. BeanFactory核心机制演示
         *    BeanFactory是Spring IoC容器的核心接口,定义了IoC容器的基础功能
         */

        // 2.1 获取BeanFactory中注册的Bean(演示BeanFactory的getBean方法)
        //    myBeanFactoryPostProcessor是一个BeanFactory后置处理器,用于定制Bean定义
        context.getBean("myBeanFactoryPostProcessor");

        // 记录容器标识信息(演示ApplicationContext的toString实现)
        Logger.info(context);

        /*
         * 3. 深入BeanFactory内部实现(通过反射访问私有字段)
         *    DefaultSingletonBeanRegistry是DefaultSingletonBeanRegistry的核心实现类
         *    该类维护了单例Bean的缓存池singletonObjects
         */
        // 通过反射获取DefaultSingletonBeanRegistry的singletonObjects字段
        Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
        singletonObjects.setAccessible(true); // 突破私有权限限制

        // 获取BeanFactory实例(ConfigurableListableBeanFactory是可配置的Bean工厂接口)
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();

        // 获取单例Bean缓存对象(实际类型为ConcurrentHashMap)
        Object obj = singletonObjects.get(beanFactory);
        Map<String, Object> map = ObjectUtil.cast(obj); // 类型转换

        // 遍历并记录所有以"myBean"开头的单例Bean
        map.forEach((k, v) -> {
            if (k.startsWith("myBean")) {
                String s = k + "=" + v.toString(); // 构造日志信息
                Logger.info(s); // 输出Bean名称及实例信息
            }
            // 打印所有单例Bean
            //  Logger.info("Singleton Bean: {} = {}", k, v.getClass().getName()));
        });

        /*
         * 4. ApplicationContext扩展功能演示
         *    相比BeanFactory,ApplicationContext提供更丰富的企业级功能:
         *    - 国际化消息处理(MessageSource)
         *    - 资源模式解析(ResourcePatternResolver)
         *    - 事件发布机制(ApplicationEventPublisher)
         *    - 环境变量访问(EnvironmentCapable)
         */

        // 4.1 国际化消息处理(Locale.CHINA指定中文环境)
        Logger.infoF(context.getMessage("welcome", null, Locale.CHINA));

        // 4.2 资源加载演示
        // 4.2.1 加载类路径下的application.yaml(精确匹配单个文件)
        Resource[] resourceClasspath = context.getResources("classpath:application.yaml");
        for (Resource resource : resourceClasspath) {
            Logger.infoF("classpath资源路径: {}", resource.toString()); // 输出资源定位信息
        }

        // 4.2.2 使用通配符加载所有META-INF/spring.factories(匹配jar包内资源)
        Resource[] resourceClasspathArray = context.getResources("classpath*:META-INF/spring.factories");
        for (Resource resource : resourceClasspathArray) {
            Logger.infoF("classpath*通配符资源: {}", resource.toString()); // 输出匹配的多个资源
        }

        // 4.2.3 磁盘绝对路径加载(演示文件系统资源访问)
        Resource[] resourceFile = context.getResources("file:application.yaml");
        for (Resource resource : resourceFile) {
            Logger.infoF("磁盘文件资源: {}", resource.toString()); // 输出文件系统资源详情
        }

        // 4.3 环境变量访问(演示配置属性获取)
        Logger.infoF("Java环境路径: {}", context.getEnvironment().getProperty("java_home"));
        Logger.infoF("服务器端口: {}", context.getEnvironment().getProperty("server.port"));

        /*
         * 5. 事件发布与监听机制演示
         *    展示ApplicationContext的事件驱动编程模型
         */
        // 5.1 发布自定义注册事件
        context.publishEvent(new MyRegisteredEvent(context)); // 触发事件传播

        // 5.2 调用Bean的自定义注册方法(演示Bean与上下文的交互)
        context.getBean(MyBean.class).register();

        // 查看Bean定义
        String[] beanNames = context.getBeanDefinitionNames();
        Arrays.stream(beanNames).forEach(name -> {
            try {
                // 通过 BeanFactory 获取 BeanDefinition
                BeanDefinition beanDefinition = context.getBeanFactory().getBeanDefinition(name);
                Logger.debugF("Bean Definition: {}", beanDefinition);
            } catch (Exception e) {
                Logger.errorF("Failed to get bean definition for: {}", name, e);
            }
        });
    }
}

5.2 动态注册Bean示例

package com.dwl.application_context_case.config;

import com.dwl.application_context_case.service.DynamicService;
import com.dwl.log.Logger;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

/**
 * <h2>动态Bean注册配置类</h2>
 * <p>
 * <b>核心功能:</b>
 * <ul>
 *   <li>通过编程方式动态注册Bean到Spring容器</li>
 *   <li>实现条件化Bean注册(基于Profile)</li>
 *   <li>演示BeanDefinitionRegistry的使用</li>
 * </ul>
 * </p>
 *
 * <p>
 * <b>执行原理:</b>
 * <ol>
 *   <li>应用启动时Spring容器刷新</li>
 *   <li>触发BeanFactoryPostProcessor执行阶段</li>
 *   <li>当激活{@code dynamic} Profile时,调用此注册方法</li>
 *   <li>通过BeanDefinitionRegistry动态注册Bean定义</li>
 *   <li>后续Bean实例化阶段创建动态Bean实例</li>
 * </ol>
 * </p>
 *
 * <p>
 * <b>使用场景:</b>
 * <ul>
 *   <li>需要根据运行时条件动态注册Bean</li>
 *   <li>实现插件化架构</li>
 *   <li>多租户场景下的差异化Bean注册</li>
 * </ul>
 * </p>
 *
 * @author Dwl
 * @version 1.1.0
 */
@Configuration
public class DynamicBeanRegistrar {

    /**
     * 动态注册Bean的核心方法
     * <p>
     * <b>技术要点:</b>
     * <ul>
     *   <li>使用 {@link BeanDefinitionRegistry} 直接操作Spring容器</li>
     *   <li>通过 {@link GenericBeanDefinition} 定义Bean元数据</li>
     *   <li>{@link Profile} 注解实现条件化注册</li>
     * </ul>
     * </p>
     *
     * @param registry Spring容器Bean定义注册接口
     *                 <p>
     *                 <b>生命周期:</b>
     *                 <ul>
     *                   <li>在容器刷新阶段被调用</li>
     *                   <li>早于Bean实例化阶段</li>
     *                 </ul>
     *                 </p>
     * @throws IllegalStateException 如果尝试在非dynamic Profile下注册
     */
    @Profile("prod") // 仅当激活dynamic Profile时生效
    public void registerDynamicBean(BeanDefinitionRegistry registry) {
        // 1. 创建Bean定义对象
        GenericBeanDefinition beanDef = new GenericBeanDefinition();

        // 2. 设置Bean实现类
        beanDef.setBeanClass(DynamicService.class);

        // 3. 配置作用域为原型(每次请求创建新实例)
        beanDef.setScope(BeanDefinition.SCOPE_PROTOTYPE);

        // 4. 注册Bean定义到容器
        String beanName = "dynamicService"; // 注册后的Bean名称
        registry.registerBeanDefinition(beanName, beanDef);

        // 5. 验证注册结果(调试用)
        if (registry.containsBeanDefinition(beanName)) {
            Logger.info("[DEBUG] Dynamic bean registered: " + beanName);
        }
    }
}

5.3 性能优化建议

  1. 懒加载配置​:
@Bean(lazyInit = true)
public HeavyBean heavyBean() {
    return new HeavyBean();
}
  1. 原型作用域管理​:
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE, 
       proxyMode = ScopedProxyMode.TARGET_CLASS)
public PrototypeBean prototypeBean() {
    return new PrototypeBean();
}

六、常见疑难问题解析

6.1 循环依赖解决方案

问题现象​:

***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
|  serviceA defined in file [...ServiceA.class]
↑     ↓
|  serviceB defined in file [...ServiceB.class]
└─────┘

解决方案​:

  1. 使用@Lazy延迟加载:
@Service
public class ServiceA {
    private final ServiceB serviceB;
    
    public ServiceA(@Lazy ServiceB serviceB) {
        this.serviceB = serviceB;
    }
}
  1. 构造器注入改属性注入:
@Service
public class ServiceA {
    @Autowired
    private ServiceB serviceB;
}

七、企业级应用实践

7.1 配置加密解密实现

@Component
public class DecryptingBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) {
        String[] beanNames = factory.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            BeanDefinition beanDef = factory.getBeanDefinition(beanName);
            if (beanDef.getPropertyValues().contains("password")) {
                PropertyValue value = beanDef.getPropertyValues().getPropertyValue("password");
                String encryptedPwd = (String) value.getValue();
                String decryptedPwd = AESUtil.decrypt(encryptedPwd);
                value.setValue(decryptedPwd);
            }
        }
    }
}

7.2 多环境配置切换


# application-prod.yml
server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://prod-db:3306/app

# application-dev.yml
server:
  port: 8081
spring:
  datasource:
    url: jdbc:h2:mem:devdb

启动命令:

java -jar app.jar --spring.profiles.active=prod

八、Spring 6新特性展望

  1. GraalVM原生镜像支持​:
native-image -jar app.jar --no-fallback
  1. 函数式Bean注册​:
@Configuration
public class FunctionalConfig {
    @Bean
    public Function<String, String> upperCaseConverter() {
        return s -> s.toUpperCase();
    }
}
  1. 响应式WebFlux增强​:
@Bean
public RouterFunction<ServerResponse> routes() {
    return RouterFunctions.route()
        .GET("/users", request -> 
            ServerResponse.ok().body(userService.getUsers(), User.class))
        .build();
}

九、全部完整的代码

BeanFactoryAndApplicationContext

package com.dwl.application_context_case;

import com.dwl.application_context_case.event.MyRegisteredEvent;
import com.dwl.application_context_case.service.MyBean;
import com.dwl.log.Logger;
import com.dwl.util.ObjectUtil;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Locale;
import java.util.Map;

/**
 * @ClassName BeanFactoryAndApplicationContext
 * @Description 深入探究Spring框架中BeanFactory与ApplicationContext的核心差异及协作关系
 * 通过实例演示Spring容器核心接口的使用方法,包括Bean生命周期管理、资源加载、事件发布等特性
 * @Version 1.0.0
 * @Date 2025
 * @Author By Dwl
 */
@SpringBootApplication
public class BeanFactoryAndApplicationContext {

    /**
     * 应用程序入口方法,演示Spring容器核心功能
     *
     * @param args 启动参数
     * @throws NoSuchFieldException   当访问不存在的字段时抛出
     * @throws IllegalAccessException 当字段访问权限不足时抛出
     * @throws IOException            当资源加载失败时抛出
     */
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {
        // 1. 初始化Spring应用上下文(ConfigurableApplicationContext是ApplicationContext的子接口)
        //    提供配置管理能力,支持运行时修改Bean定义和刷新上下文
        ConfigurableApplicationContext context = SpringApplication.run(BeanFactoryAndApplicationContext.class, args);

        /*
         * 2. BeanFactory核心机制演示
         *    BeanFactory是Spring IoC容器的核心接口,定义了IoC容器的基础功能
         */

        // 2.1 获取BeanFactory中注册的Bean(演示BeanFactory的getBean方法)
        //    myBeanFactoryPostProcessor是一个BeanFactory后置处理器,用于定制Bean定义
        context.getBean("myBeanFactoryPostProcessor");

        // 记录容器标识信息(演示ApplicationContext的toString实现)
        Logger.info(context);

        /*
         * 3. 深入BeanFactory内部实现(通过反射访问私有字段)
         *    DefaultSingletonBeanRegistry是DefaultSingletonBeanRegistry的核心实现类
         *    该类维护了单例Bean的缓存池singletonObjects
         */
        // 通过反射获取DefaultSingletonBeanRegistry的singletonObjects字段
        Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
        singletonObjects.setAccessible(true); // 突破私有权限限制

        // 获取BeanFactory实例(ConfigurableListableBeanFactory是可配置的Bean工厂接口)
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();

        // 获取单例Bean缓存对象(实际类型为ConcurrentHashMap)
        Object obj = singletonObjects.get(beanFactory);
        Map<String, Object> map = ObjectUtil.cast(obj); // 类型转换

        // 遍历并记录所有以"myBean"开头的单例Bean
        map.forEach((k, v) -> {
            if (k.startsWith("myBean")) {
                String s = k + "=" + v.toString(); // 构造日志信息
                Logger.info(s); // 输出Bean名称及实例信息
            }
            // 打印所有单例Bean
            //  Logger.info("Singleton Bean: {} = {}", k, v.getClass().getName()));
        });

        /*
         * 4. ApplicationContext扩展功能演示
         *    相比BeanFactory,ApplicationContext提供更丰富的企业级功能:
         *    - 国际化消息处理(MessageSource)
         *    - 资源模式解析(ResourcePatternResolver)
         *    - 事件发布机制(ApplicationEventPublisher)
         *    - 环境变量访问(EnvironmentCapable)
         */

        // 4.1 国际化消息处理(Locale.CHINA指定中文环境)
        Logger.infoF(context.getMessage("welcome", null, Locale.CHINA));

        // 4.2 资源加载演示
        // 4.2.1 加载类路径下的application.yaml(精确匹配单个文件)
        Resource[] resourceClasspath = context.getResources("classpath:application.yaml");
        for (Resource resource : resourceClasspath) {
            Logger.infoF("classpath资源路径: {}", resource.toString()); // 输出资源定位信息
        }

        // 4.2.2 使用通配符加载所有META-INF/spring.factories(匹配jar包内资源)
        Resource[] resourceClasspathArray = context.getResources("classpath*:META-INF/spring.factories");
        for (Resource resource : resourceClasspathArray) {
            Logger.infoF("classpath*通配符资源: {}", resource.toString()); // 输出匹配的多个资源
        }

        // 4.2.3 磁盘绝对路径加载(演示文件系统资源访问)
        Resource[] resourceFile = context.getResources("file:application.yaml");
        for (Resource resource : resourceFile) {
            Logger.infoF("磁盘文件资源: {}", resource.toString()); // 输出文件系统资源详情
        }

        // 4.3 环境变量访问(演示配置属性获取)
        Logger.infoF("Java环境路径: {}", context.getEnvironment().getProperty("java_home"));
        Logger.infoF("服务器端口: {}", context.getEnvironment().getProperty("server.port"));

        /*
         * 5. 事件发布与监听机制演示
         *    展示ApplicationContext的事件驱动编程模型
         */
        // 5.1 发布自定义注册事件
        context.publishEvent(new MyRegisteredEvent(context)); // 触发事件传播

        // 5.2 调用Bean的自定义注册方法(演示Bean与上下文的交互)
        context.getBean(MyBean.class).register();

        // 查看Bean定义
        String[] beanNames = context.getBeanDefinitionNames();
        Arrays.stream(beanNames).forEach(name -> {
            try {
                // 通过 BeanFactory 获取 BeanDefinition
                BeanDefinition beanDefinition = context.getBeanFactory().getBeanDefinition(name);
                Logger.debugF("Bean Definition: {}", beanDefinition);
            } catch (Exception e) {
                Logger.errorF("Failed to get bean definition for: {}", name, e);
            }
        });
    }
}

AppConfig

package com.dwl.application_context_case.config;

import com.dwl.application_context_case.event.MyMonitor;
import com.dwl.application_context_case.processor.MyBeanFactoryPostProcessor;
import com.dwl.application_context_case.service.ProdAuditService;
import com.dwl.log.Logger;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import javax.sql.DataSource;
import java.util.Map;
import java.util.concurrent.Executor;

/**
 * @ClassName MyBean
 * @Description <h2>应用配置中心</h2>
 * <p>
 * <b>核心功能:</b>
 * <ul>
 *   <li>数据源配置</li>
 *   <li>异步线程池管理</li>
 *   <li>环境感知的Bean注册</li>
 *   <li>多租户数据源路由</li>
 * </ul>
 * </p>
 *
 * <p>
 * <b>配置加载顺序:</b>
 * <ol>
 *   <li>通过 {@link #dataSource()} 加载数据源配置</li>
 *   <li>通过 {@link #asyncExecutor()} 初始化线程池</li>
 *   <li>根据 Profile 注册条件化 Bean</li>
 *   <li>通过 {@link #beanFactoryPostProcessor()} 动态注册生产环境 Bean</li>
 * </ol>
 * </p>
 * @Version 1.0.0
 * @Date 2025
 * @Author By Dwl
 */
@Configuration
@ComponentScan(basePackages = "com.dwl.application_context_case.service")
@EnableAsync
@Data
@NoArgsConstructor // 添加无参构造器供CGLIB代理使用
public class AppConfig {

    /**
     * Spring环境对象(必须通过构造器注入)
     */
    private Environment env;

    /**
     * <h3>构造器注入 Environment</h3>
     * <p>
     * 使用构造器注入确保 Spring 在创建代理时能正确完成依赖注入<br>
     * 注意:Lombok 的 {@code @NoArgsConstructor} 已移除以避免代理问题
     * </p>
     *
     * @param env Spring 环境对象(通过 {@link org.springframework.context.annotation.Configuration} 自动注入)
     */
    @Autowired
    public AppConfig(Environment env) {
        this.env = env;
        Logger.infoF("AppConfig initialized with environment: {}", env.getProperty("spring.profiles.active"));
    }


    /**
     * <h3>数据源配置</h3>
     * <p>
     * 使用 HikariCP 连接池,参数从环境变量读取<br>
     * 示例配置(application-prod.properties):
     * <pre>
     * spring.datasource.url=jdbc:mysql://prod-db:3306/mdb
     * spring.datasource.username=prod_user
     * spring.datasource.password=prod_password
     * </pre>
     * </p>
     */
    @Bean
    public DataSource dataSource() {
        Logger.debug("Initializing DataSource...");
//        HikariDataSource dataSource = new HikariDataSource();
//        dataSource.setJdbcUrl(env.getProperty("spring.datasource.url"));
//        dataSource.setUsername(env.getProperty("spring.datasource.username"));
//        dataSource.setPassword(env.getProperty("spring.datasource.password"));
//
//        // 连接池配置
//        dataSource.setMaximumPoolSize(20);
//        dataSource.setMinimumIdle(5);
//        dataSource.setIdleTimeout(30000);
        Logger.info("DataSource configured successfully");
        return null;
    }

    /**
     * <h3>异步线程池配置</h3>
     * <p>
     * 核心参数:
     * <ul>
     *   <li>corePoolSize: 5(最小工作线程数)</li>
     *   <li>maxPoolSize: 20(最大并发线程数)</li>
     *   <li>queueCapacity: 100(任务队列容量)</li>
     * </ul>
     * </p>
     */
    @Bean(name = "asyncExecutor")
    public Executor asyncExecutor() {
        Logger.debug("Configuring async executor...");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("Async-");
        executor.initialize();
        Logger.infoF("Async executor [{}] initialized", executor.getThreadNamePrefix());
        return executor;
    }

    /**
     * <h3>环境感知的监听器注册</h3>
     * <p>
     * 仅在开发环境 ({@code dev} Profile) 注册调试监听器<br>
     * 使用 {@link Profile} 注解实现条件化 Bean 注册
     * </p>
     */
    @Bean
    @Profile("dev")
    public MyMonitor devEventMonitor() {
        Logger.info("Registering dev environment monitor");
        return new MyMonitor(true); // 启用调试模式
    }

    /**
     * <h3>Bean工厂后处理器</h3>
     * <p>
     * 动态注册生产环境专用 Bean<br>
     * 通过实现 {@link EnvironmentAware} 直接获取环境变量
     * </p>
     */
    @Bean
    public MyBeanFactoryPostProcessor beanFactoryPostProcessor() {
        return new MyBeanFactoryPostProcessorImpl();
    }

    /**
     * <h4>Bean工厂后处理器实现</h4>
     * <p>
     * 通过 {@link EnvironmentAware} 获取环境变量,避免构造器注入问题<br>
     * 仅在激活 {@code prod} Profile 时注册审计服务
     * </p>
     */
    private static class MyBeanFactoryPostProcessorImpl extends MyBeanFactoryPostProcessor implements EnvironmentAware {
        private Environment env;

        @Override
        public void setEnvironment(@NonNull Environment environment) {
            this.env = environment;
            Logger.debug("Environment set in MyBeanFactoryPostProcessorImpl");
        }

        @Override
        public void postProcessBeanFactory(@NonNull ConfigurableListableBeanFactory factory) {
            super.postProcessBeanFactory(factory);
            if (env.acceptsProfiles(Profiles.of("prod"))) {
                Logger.info("Activating production profile - registering ProdAuditService");
                registerProductionBeans(factory);
            }
        }

        private void registerProductionBeans(ConfigurableListableBeanFactory factory) {
            GenericBeanDefinition auditDef = new GenericBeanDefinition();
            auditDef.setBeanClass(ProdAuditService.class);
            ((BeanDefinitionRegistry) factory).registerBeanDefinition("auditService", auditDef);
            Logger.info("ProdAuditService registered successfully");
        }
    }

    /**
     * <h3>多租户数据源配置</h3>
     * <p>
     * 通过 {@link ConfigurationProperties} 绑定配置前缀<br>
     * 示例配置(application.yml):
     * <pre>
     * spring:
     *   tenant:
     *     defaultSchema: public
     *     schemaMappings:
     *       tenant1: schema1
     *       tenant2: schema2
     * </pre>
     * </p>
     */
    @Bean
    @ConfigurationProperties(prefix = "spring.tenant")
    public TenantConfig tenantConfig() {
        return new TenantConfig();
    }

    @Data
    public static class TenantConfig {
        /**
         * 默认数据库 Schema
         */
        private String defaultSchema;

        /**
         * 租户ID到Schema的映射关系
         */
        private Map<String, String> schemaMappings;
    }

}

AsyncEventListener

package com.dwl.application_context_case.config;

import com.dwl.application_context_case.event.MyRegisteredEvent;
import com.dwl.log.Logger;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
 * 异步事件监听器组件
 * <p>
 * 该类用于异步处理应用程序中发布的特定事件,通过Spring的事件监听机制与异步执行结合,
 * 实现非阻塞的业务逻辑处理。适用于需要解耦且耗时较长的操作场景(如发送通知、日志记录等)。
 * </p>
 *
 * <p>
 * 主要功能:
 * 1. 监听 {@link MyRegisteredEvent} 用户注册成功事件
 * 2. 使用异步线程池处理事件回调
 * 3. 实现业务逻辑的解耦和非阻塞执行
 * 4. 记录完整的事件处理日志(包括正常流程和异常情况)
 * </p>
 *
 * @author By Dwl
 * @version 1.0.0
 * @see org.springframework.context.event.EventListener
 * @see org.springframework.scheduling.annotation.Async
 * @since 2025
 */
@Component
public class AsyncEventListener {

    private static final String EVENT_SUCCESS = "Event processed successfully";
    private static final String EVENT_FAIL = "Event processing failed";

    /**
     * 异步处理用户注册成功事件
     * <p>
     * 当系统中发布{@link MyRegisteredEvent}事件时,此方法会被触发执行。
     * 方法使用指定的异步线程池执行,避免阻塞主线程。
     * </p>
     *
     * <p>
     * 日志记录策略:
     * 1. 方法入口:记录事件接收信息(INFO级别)
     * 2. 业务处理:记录关键业务参数(DEBUG级别)
     * 3. 成功退出:记录处理结果(INFO级别)
     * 4. 异常捕获:记录完整错误堆栈(ERROR级别)
     * </p>
     *
     * @param event 用户注册事件对象,包含注册相关的业务数据
     *              <ul>
     *                  <li>userId: 新注册用户的唯一标识</li>
     *                  <li>userName: 用户名称</li>
     *                  <li>registerTime: 注册时间戳</li>
     *              </ul>
     * @see MyRegisteredEvent 事件对象定义
     * @see org.springframework.scheduling.annotation.Async 异步执行注解
     * @see org.springframework.context.event.EventListener 事件监听注解
     */
    @Async("asyncExecutor")  // 使用名为"eventExecutor"的自定义线程池
    @EventListener        // 标记为事件监听方法
    public void handleAsyncEvent(MyRegisteredEvent event) {
        // 记录事件接收日志(包含事件关键信息)
        Logger.infoF("Received async event - User Registration: {}", event);

        try {
            // 业务参数记录(DEBUG级别,生产环境可关闭)
            // Logger.debug("Processing event with parameters - userId: {}, userName: {}, registerTime: {}",
            //        event.getUserId(), event.getUserName(), event.getRegisterTime());

            // 1. 获取事件携带的业务数据
            // Long userId = event.getUserId();
            // String userName = event.getUserName();

            // 2. 执行实际业务操作(示例伪代码)
            // sendWelcomeEmail(userId, userName);
            // logRegistrationEvent(event);

            // 模拟业务处理
            Thread.sleep(1000);  // 模拟耗时操作

            // 记录成功日志(带业务标识)
            // Logger.infoF("{} - User {} registration processed successfully", EVENT_SUCCESS, userId);

        } catch (InterruptedException e) {
            // 记录中断异常(保留原始堆栈)
            Thread.currentThread().interrupt();  // 重置中断状态
            // Logger.errorF("{} failed for event [{}] - Error: {}", EVENT_FAIL, event.getId(), e.getMessage(), e);

        } catch (Exception e) {
            // 记录业务处理异常(带事件标识)
            Logger.errorF("{} failed for event - Error: {}",
                    EVENT_FAIL, e.getMessage());

            // 可根据需要在此处添加:
            // 1. 异常分类处理
            // 2. 重试机制
            // 3. 死信队列投递
        }
    }
}

DynamicBeanRegistrar

package com.dwl.application_context_case.config;

import com.dwl.application_context_case.service.DynamicService;
import com.dwl.log.Logger;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

/**
 * <h2>动态Bean注册配置类</h2>
 * <p>
 * <b>核心功能:</b>
 * <ul>
 *   <li>通过编程方式动态注册Bean到Spring容器</li>
 *   <li>实现条件化Bean注册(基于Profile)</li>
 *   <li>演示BeanDefinitionRegistry的使用</li>
 * </ul>
 * </p>
 *
 * <p>
 * <b>执行原理:</b>
 * <ol>
 *   <li>应用启动时Spring容器刷新</li>
 *   <li>触发BeanFactoryPostProcessor执行阶段</li>
 *   <li>当激活{@code dynamic} Profile时,调用此注册方法</li>
 *   <li>通过BeanDefinitionRegistry动态注册Bean定义</li>
 *   <li>后续Bean实例化阶段创建动态Bean实例</li>
 * </ol>
 * </p>
 *
 * <p>
 * <b>使用场景:</b>
 * <ul>
 *   <li>需要根据运行时条件动态注册Bean</li>
 *   <li>实现插件化架构</li>
 *   <li>多租户场景下的差异化Bean注册</li>
 * </ul>
 * </p>
 *
 * @author Dwl
 * @version 1.1.0
 */
@Configuration
public class DynamicBeanRegistrar {

    /**
     * 动态注册Bean的核心方法
     * <p>
     * <b>技术要点:</b>
     * <ul>
     *   <li>使用 {@link BeanDefinitionRegistry} 直接操作Spring容器</li>
     *   <li>通过 {@link GenericBeanDefinition} 定义Bean元数据</li>
     *   <li>{@link Profile} 注解实现条件化注册</li>
     * </ul>
     * </p>
     *
     * @param registry Spring容器Bean定义注册接口
     *                 <p>
     *                 <b>生命周期:</b>
     *                 <ul>
     *                   <li>在容器刷新阶段被调用</li>
     *                   <li>早于Bean实例化阶段</li>
     *                 </ul>
     *                 </p>
     * @throws IllegalStateException 如果尝试在非dynamic Profile下注册
     */
    @Profile("prod") // 仅当激活dynamic Profile时生效
    public void registerDynamicBean(BeanDefinitionRegistry registry) {
        // 1. 创建Bean定义对象
        GenericBeanDefinition beanDef = new GenericBeanDefinition();

        // 2. 设置Bean实现类
        beanDef.setBeanClass(DynamicService.class);

        // 3. 配置作用域为原型(每次请求创建新实例)
        beanDef.setScope(BeanDefinition.SCOPE_PROTOTYPE);

        // 4. 注册Bean定义到容器
        String beanName = "dynamicService"; // 注册后的Bean名称
        registry.registerBeanDefinition(beanName, beanDef);

        // 5. 验证注册结果(调试用)
        if (registry.containsBeanDefinition(beanName)) {
            Logger.info("[DEBUG] Dynamic bean registered: " + beanName);
        }
    }
}

MyMonitor

package com.dwl.application_context_case.event;

import com.dwl.application_context_case.service.MyBean;
import com.dwl.log.Logger;
import lombok.Data;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.context.ApplicationEvent;

/**
 * <h2>事件监听器组件</h2>
 * <p>
 * <b>功能定位:</b>实现 Spring 事件驱动模型的监听器组件,用于响应自定义事件
 * <br>
 * <b>设计模式:</b>观察者模式(发布-订阅模式)
 * <br>
 * <b>应用场景:</b>
 * <ul>
 *   <li>系统监控指标采集</li>
 *   <li>业务流程状态跟踪</li>
 *   <li>跨组件异步通知</li>
 *   <li>审计日志记录</li>
 * </ul>
 * </p>
 *
 * <p>
 * <b>与 ApplicationListener 的对比:</b>
 * <table border="1">
 *   <tr><th></th><th>@EventListener</th><th>ApplicationListener</th></tr>
 *   <tr><td>实现方式</td><td>基于注解的声明式监听</td><td>接口实现式监听</td></tr>
 *   <tr><td>事件过滤</td><td>支持 SpEL 表达式过滤</td><td>需手动实现过滤逻辑</td></tr>
 *   <tr><td>方法签名</td><td>灵活(支持任意参数)</td><td>固定 EventListener 接口</td></tr>
 *   <tr><td>异步支持</td><td>需配合 @Async</td><td>需配置 TaskExecutor</td></tr>
 * </table>
 * </p>
 *
 * @Version 1.0.0
 * @Date 2025
 * @Author By Dwl
 */
@Component
@Data
public class MyMonitor {

    private boolean debugMode;

    public MyMonitor(boolean debugMode) {
        this.debugMode = debugMode;
    }

    public MyMonitor() {
    }

    /**
     * <h3>事件处理方法</h3>
     * <p>
     * <b>触发条件:</b>当容器中发布 MyRegisteredEvent 事件时自动触发
     * <br>
     * <b>执行线程:</b>默认与事件发布线程同步执行(可通过 @Async 异步化)
     * <br>
     * <b>事件生命周期:</b>
     * <ol>
     *   <li>事件发布(context.publishEvent())</li>
     *   <li>事件多播(通过 ApplicationEventMulticaster)</li>
     *   <li>事件监听器执行</li>
     * </ol>
     * </p>
     *
     * <p>
     * <b>参数解析:</b>
     * <ul>
     *   <li>{@code event} - 事件对象,包含以下关键信息:
     *     <ul>
     *       <li>事件源对象(通过 getSource() 获取)</li>
     *       <li>时间戳(通过 getTimestamp() 获取)</li>
     *       <li>自定义业务数据(需在事件类中定义)</li>
     *     </ul>
     *   </li>
     * </ul>
     * </p>
     *
     * <p>
     * <b>扩展能力:</b>
     * <ul>
     *   <li>支持事件过滤(通过 condition 属性)</li>
     *   <li>支持异步处理(通过 @Async 注解)</li>
     *   <li>支持事件响应链(多个监听器顺序执行)</li>
     * </ul>
     * </p>
     *
     * @param event 事件对象(必须非空)
     * @see MyRegisteredEvent 事件定义类
     * @see ApplicationEvent 发布事件的基类
     */
    @EventListener
    public void monitor(MyRegisteredEvent event) {

        if (debugMode) {
            Logger.debug("调试模式启用");
        }

        // 1. 记录事件基本信息
        Logger.infoF("【事件监听】收到事件 - 类型={} | 来源={}",
                event.getClass().getSimpleName(), event.getSource());

        // 2. 提取事件携带的业务数据(示例)
        // Object data = event.getData();

        // 3. 异常处理(建议捕获特定异常)
        try {
            // 业务处理逻辑
            processEventData(event);
        } catch (Exception e) {
            Logger.error("事件处理异常", e);
        }
    }

    /**
     * <h4>事件数据处理方法</h4>
     * <p>
     * <b>设计要点:</b>
     * <ul>
     *   <li>解耦事件处理逻辑</li>
     *   <li>支持业务数据校验</li>
     *   <li>可扩展为责任链模式</li>
     * </ul>
     * </p>
     *
     * @param event 事件对象
     */
    private void processEventData(MyRegisteredEvent event) {
        // 示例:提取事件源对象
        Object source = event.getSource();
        if (source instanceof MyBean) {
            Logger.debugF("处理来自 MyBean 的事件");
        }
    }
}

MyRegisteredEvent

package com.dwl.application_context_case.event;

import com.dwl.application_context_case.service.MyBean;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;

/**
 * <h2>自定义应用事件类</h2>
 * <p>
 * <b>功能定位:</b>实现 Spring 事件驱动模型的核心事件载体,用于封装组件注册状态变更通知
 * <br>
 * <b>设计模式:</b>观察者模式(发布-订阅模式)
 * <br>
 * <b>继承体系:</b>
 * <ul>
 *   <li>{@link ApplicationEvent} - Spring 事件基类</li>
 *   <li>{@code MyRegisteredEvent} - 业务层自定义事件</li>
 * </ul>
 * </p>
 *
 * <p>
 * <b>典型应用场景:</b>
 * <ul>
 *   <li>组件注册状态变更通知</li>
 *   <li>跨模块业务状态同步</li>
 *   <li>异步审计日志记录</li>
 *   <li>微服务间事件总线通信</li>
 * </ul>
 * </p>
 *
 * <p>
 * <b>事件传播机制:</b>
 * <ol>
 *   <li>同步传播:默认通过当前线程传递(通过 {@link ApplicationEventPublisher#publishEvent})</li>
 *   <li>异步传播:需配合 {@link org.springframework.scheduling.annotation.Async} 注解</li>
 * </ol>
 * </p>
 *
 * @Version 1.0.0
 * @Date 2025
 * @Author By Dwl
 */
public class MyRegisteredEvent extends ApplicationEvent {

    /**
     * <h3>事件构造方法</h3>
     * <p>
     * <b>核心功能:</b>创建包含事件源信息的事件对象
     * <br>
     * <b>设计要点:</b>
     * <ul>
     *   <li>事件源对象必须实现 {@link java.io.Serializable} 接口(序列化要求)</li>
     *   <li>建议事件源对象包含唯一标识符(用于事件追踪)</li>
     *   <li>构造方法参数需满足线程安全要求</li>
     * </ul>
     * </p>
     *
     * @param source 事件源对象(通常为事件发布者)
     *             <ul>
     *               <li>类型约束:建议使用具体业务对象(如 MyBean 实例)</li>
     *               <li>null 值限制:Spring 框架禁止 source=null 的情况</li>
     *             </ul>
     *
     * @throws IllegalArgumentException 当 source 参数不符合要求时抛出
     * @see MyBean#register() 事件发布示例
     */
    public MyRegisteredEvent(Object source) {
        super(source);

        // 防御性编程:验证事件源有效性
        if (source == null) {
            throw new IllegalArgumentException("Event source cannot be null");
        }
    }

    /**
     * <h4>获取事件源对象</h4>
     * <p>
     * <b>访问方法:</b>通过 {@link #getSource()} 方法获取
     * <br>
     * <b>数据契约:</b>
     * <ul>
     *   <li>返回值类型:Object(建议强制转换为具体业务类型)</li>
     *   <li>空值保证:Spring 框架保证非空</li>
     * </ul>
     * </p>
     *
     * @return 事件源对象(通常是事件发布者实例)
     * @see MyBean#register() 典型事件源对象类型
     */
    @Override
    public Object getSource() {
        return super.getSource();
    }

    /**
     * <h4>事件唯一标识生成</h4>
     * <p>
     * <b>设计目标:</b>提供事件追踪能力
     * <br>
     * <b>实现方式:</b>组合事件类名和时间戳生成唯一标识
     * </p>
     *
     * @return 格式:{@code MyRegisteredEvent@timestamp}
     * @example "MyRegisteredEvent@1625097600000"
     */
    public String getEventId() {
        return this.getClass().getSimpleName() + "@" + super.getTimestamp();
    }

    /**
     * <h4>事件数据校验方法</h4>
     * <p>
     * <b>校验策略:</b>确保事件数据的完整性
     * <br>
     * <b>扩展建议:</b>可添加业务字段校验逻辑
     * </p>
     *
     * @throws IllegalStateException 当检测到无效事件数据时抛出
     */
    public void validate() {
        if (getSource() == null) {
            throw new IllegalStateException("Invalid event state: source is null");
        }
    }
}

MyBeanFactoryPostProcessor

package com.dwl.application_context_case.processor;

import com.dwl.log.Logger;
import lombok.NonNull;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.stereotype.Component;

/**
 * <h2>BeanFactory 后置处理器</h2>
 * <p>
 * <b>功能定位:</b>实现 Spring 容器的核心扩展点,允许在 Bean 实例化前修改 Bean 定义
 * <br>
 * <b>执行时机:</b>在以下阶段执行:
 * <ol>
 *   <li>容器初始化完成(BeanFactory 标准初始化)</li>
 *   <li>所有 BeanDefinition 加载完成后</li>
 *   <li>在 Bean 实例化、属性填充、初始化方法执行之前</li>
 * </ol>
 * </p>
 *
 * <p>
 * <b>核心能力:</b>
 * <ul>
 *   <li>动态修改 Bean 定义属性(scope/lazy-init/data-type 等)</li>
 *   <li>注册新的 BeanDefinition(支持动态扩展 Bean)</li>
 *   <li>执行占位符替换(如数据库密码解密)</li>
 *   <li>覆盖已存在的 Bean 定义(需注意优先级问题)</li>
 * </ul>
 * </p>
 *
 * <p>
 * <b>与 BeanPostProcessor 的区别:</b>
 * <table border="1">
 *   <tr><th></th><th>BeanFactoryPostProcessor</th><th>BeanPostProcessor</th></tr>
 *   <tr><td>作用阶段</td><td>Bean 实例化前</td><td>Bean 实例化后</td></tr>
 *   <tr><td>操作对象</td><td>BeanDefinition</td><td>Bean 实例</td></tr>
 *   <tr><td>执行顺序</td><td>优先执行</td><td>后续执行</td></tr>
 * </table>
 * </p>
 *
 * <p>
 * <b>典型应用场景:</b>
 * <ul>
 *   <li>加密配置解密(如数据库密码动态解密)</li>
 *   <li>多环境配置切换(根据 Profile 修改 Bean 定义)</li>
 *   <li>自动装配第三方库的 Bean(无源码类库的 Bean 注册)</li>
 *   <li>动态补全默认配置(自动设置缺省属性值)</li>
 * </ul>
 * </p>
 *
 * @Version 1.0.0
 * @Date 2025
 * @Author By Dwl
 */
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    /**
     * <h3>BeanFactory 后置处理方法</h3>
     * <p>
     * <b>参数解析:</b>
     * <ul>
     *   <li>{@code factory} - 可配置的 BeanFactory 实例,提供以下关键能力:
     *     <ul>
     *       <li>{@link ConfigurableListableBeanFactory#getBeanDefinition(String)} - 获取 Bean 定义</li>
     *       <li>{@link BeanDefinitionRegistry#registerBeanDefinition(String, BeanDefinition)} - 注册新定义</li>
     *       <li>{@link BeanDefinitionRegistry#removeBeanDefinition(String)} - 移除定义</li>
     *       <li>{@link ConfigurableListableBeanFactory#resolveEmbeddedValue(String)} - 占位符解析</li>
     *     </ul>
     *   </li>
     * </ul>
     * </p>
     *
     * <p>
     * <b>执行流程示例:</b>
     * <pre>
     * 1. 获取所有 BeanDefinition 名称
     * String[] beanNames = factory.getBeanDefinitionNames();
     *
     * 2. 遍历处理特定 Bean
     * for (String name : beanNames) {
     *     if (name.startsWith("thirdParty")) {
     *         BeanDefinition def = factory.getBeanDefinition(name);
     *         def.setScope(BeanDefinition.SCOPE_PROTOTYPE);
     *         def.setLazyInit(true);
     *     }
     * }
     *
     * 3. 动态注册新 Bean
     * GenericBeanDefinition newDef = new GenericBeanDefinition();
     * newDef.setBeanClassName("com.example.DynamicBean");
     * ((BeanDefinitionRegistry) factory).registerBeanDefinition("dynamicBean", newDef);
     * </pre>
     * </p>
     *
     * <p>
     * <b>注意事项:</b>
     * <ul>
     *   <li>执行时机仅一次(容器刷新时触发)</li>
     *   <li>不能修改已实例化的 Bean</li>
     *   <li>需避免循环依赖问题</li>
     *   <li>修改操作需线程安全</li>
     * </ul>
     * </p>
     *
     * @param factory 可配置的 BeanFactory 实例(必须非空)
     */
    @Override
    public void postProcessBeanFactory(@NonNull ConfigurableListableBeanFactory factory) {
        // 1. 记录处理器启动(可用于调试时确认执行顺序)
        Logger.info("【BeanFactory 后置处理器】开始执行");

        // 2. 获取所有已注册的 BeanDefinition 名称
        String[] beanNames = factory.getBeanDefinitionNames();
        Logger.debugF("发现 {} 个 BeanDefinition", beanNames.length);

        // 3. 遍历处理 Bean 定义(示例:修改特定前缀的 Bean)
        for (String beanName : beanNames) {
            // 3.1 获取 Bean 定义对象
            BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);

            // 3.2 示例:为所有 Service 层 Bean 添加缓存代理
            if (beanName.endsWith("Service")) {
                // 3.2.1 修改作用域为原型(如果需要)
                if (BeanDefinition.SCOPE_SINGLETON.equals(beanDefinition.getScope())) {
                    beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
                    Logger.infoF("修改 Bean 【%s】 作用域为 PROTOTYPE", beanName);
                }

                // 3.2.2 添加自定义属性(需配合 @Value 使用)
                // MutablePropertyValues values = beanDefinition.getPropertyValues();
                // values.add("cacheEnabled", true);
            }

            // 3.3 示例:解析加密的数据库密码(需实现具体解密逻辑)
            // String encryptedPwd = beanDefinition.getPropertyValues().getProperty("password");
            // String decryptedPwd = decrypt(encryptedPwd);
            // beanDefinition.getPropertyValues().add("password", decryptedPwd);
        }

        // 4. 动态注册新 Bean(示例:注册监控切面)
        // GenericBeanDefinition aspectDef = new GenericBeanDefinition();
        // aspectDef.setBeanClass(MonitorAspect.class);
        // ((BeanDefinitionRegistry) factory).registerBeanDefinition("monitorAspect", aspectDef);

        // 5. 执行完成记录
        Logger.info("【BeanFactory 后置处理器】执行完成");
    }
}

MyBeanPostProcessor

package com.dwl.application_context_case.processor;

import com.dwl.log.Logger;
import lombok.NonNull;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

/**
 * @ClassName MyBeanPostProcessor
 * @Description <p>
 * Spring 容器核心扩展点:BeanFactory 后置处理器
 * <br>
 * 实现 BeanFactory 初始化完成后、Bean 实例化前的 BeanDefinition 修改能力
 * </p>
 *
 * <p>
 * 典型应用场景:
 * <ul>
 *   <li>动态修改 Bean 定义属性(如数据源密码解密)</li>
 *   <li>占位符替换(PropertyPlaceholderConfigurer)</li>
 *   <li>Bean 定义重写(覆盖默认配置)</li>
 *   <li>注册自定义 BeanDefinition(动态注册 Bean)</li>
 * </ul>
 * </p>
 *
 * <p>
 * 执行时机:
 * <ol>
 *   <li>在 BeanFactory 标准初始化完成后</li>
 *   <li>在所有 Bean 实例化之前</li>
 *   <li>优先于 BeanPostProcessor 执行</li>
 * </ol>
 * </p>
 * @Version 1.0.0
 * @Date 2025
 * @Author By Dwl
 */
@Component
public class MyBeanPostProcessor implements BeanFactoryPostProcessor {
    /**
     * BeanFactory 初始化后置处理方法
     * <p>
     * 核心能力:
     * 1. 获取所有 BeanDefinition 进行修改
     * 2. 动态注册新的 BeanDefinition
     * 3. 修改 Bean 定义的元数据信息
     * </p>
     *
     * <p>
     * 参数说明:
     * <ul>
     *   <li>{@code factory} - 可配置的 BeanFactory 实例
     *     <ul>
     *       <li>提供访问 BeanDefinition 的 API</li>
     *       <li>支持修改 Bean 定义属性</li>
     *       <li>可以注册新的 BeanDefinition</li>
     *     </ul>
     *   </li>
     * </ul>
     * </p>
     *
     * <p>
     * 扩展说明:
     * <ul>
     *   <li>该方法在整个容器生命周期中只执行一次</li>
     *   <li>典型的实现类:PropertyPlaceholderConfigurer</li>
     *   <li>与 BeanPostProcessor 的区别:
     *     <ul>
     *       <li>作用阶段:BeanFactoryPostProcessor 在 Bean 实例化前执行</li>
     *       <li>作用对象:操作 BeanDefinition 而非 Bean 实例</li>
     *     </ul>
     *   </li>
     * </ul>
     * </p>
     */
    @Override
    public void postProcessBeanFactory(@NonNull ConfigurableListableBeanFactory factory) {
        Logger.info("【BeanFactory 后置处理器】开始修改 Bean 定义");

        // 1. 获取所有 BeanDefinition 的名称
        String[] beanNames = factory.getBeanDefinitionNames();

        // 2. 遍历所有 BeanDefinition(示例仅处理特定 Bean)
        for (String beanName : beanNames) {
            BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);

            // 3. 修改特定 Bean 的属性(示例:设置懒加载)
            if (beanName.startsWith("myBean")) {
                // 修改作用域为原型(prototype)
                beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);

                // 设置懒加载(需配合 @Lazy 注解使用)
                // beanDefinition.setLazyInit(true);

                // 示例:修改构造函数参数
                // ConstructorArgumentValues args = new ConstructorArgumentValues();
                // args.addGenericArgumentValue("customValue");
                // beanDefinition.setConstructorArgumentValues(args);

                Logger.infoF("已修改 BeanDefinition 【{}】:作用域={}",
                        beanName, beanDefinition.getScope());
            }
        }

        // 4. 动态注册新的 BeanDefinition(示例)
        // GenericBeanDefinition newBeanDef = new GenericBeanDefinition();
        // newBeanDef.setBeanClass(SomeClass.class);
        // ((BeanDefinitionRegistry) factory).registerBeanDefinition("newBean", newBeanDef);

        Logger.info("【BeanFactory 后置处理器】Bean 定义修改完成");
    }
}

DynamicService

package com.dwl.application_context_case.service;

import com.dwl.application_context_case.config.DynamicBeanRegistrar;
import com.dwl.log.Logger;

/**
 * @ClassName DynamicService
 * @Description <h2>动态服务示例</h2>
 * <p>
 * <b>核心功能:</b>
 * <ul>
 *   <li>演示通过编程方式动态注册Bean</li>
 *   <li>验证BeanFactoryPostProcessor的使用</li>
 *   <li>展示原型作用域(Prototype Scope)行为</li>
 * </ul>
 * </p>
 *
 * <p>
 * <b>关键约束:</b>
 * <ul>
 *   <li>必须移除 {@code @Service} 注解(否则会与动态注册冲突)</li>
 *   <li>只能通过 {@link DynamicBeanRegistrar} 注册到容器</li>
 *   <li>需激活 {@code dynamic} Profile 才能生效</li>
 * </ul>
 * </p>
 *
 * <p>
 * <b>使用示例:</b>
 * <pre>
 * {@code
 * // 在需要使用的位置注入(需确保Profile激活)
 * @Autowired(required = false)
 * private DynamicService dynamicService;
 *
 * if (dynamicService != null) {
 *     dynamicService.performDynamicAction();
 * }
 * }
 * </pre>
 * </p>
 * @Version 1.0.0
 * @Date 2025
 * @Author By Dwl
 */
public class DynamicService {

    /**
     * 执行动态操作
     * <p>
     * <b>行为特征:</b>
     * <ul>
     * <li>每次调用都会记录独立日志(因原型作用域每次创建新实例)</li>
     * <li>无状态服务(不依赖成员变量)</li>
     * </ul>
     */
    public void performDynamicAction() {
        Logger.info("[DynamicService] 执行动态操作 - 实例ID: " + this.hashCode());
    }

    /**
     * 验证动态注册是否成功的辅助方法
     * <p>
     * <b>使用场景:</b>
     * <ul>
     *   <li>单元测试中验证Bean注册</li>
     *   <li>调试时检查动态Bean是否存在</li>
     * </ul>
     */
    public static boolean isRegistered() {
        // 实际实现需通过ApplicationContext获取Bean定义
        // 此处仅为示例,需配合测试框架使用
        return false;
    }
}

DynamicServiceConsumer

package com.dwl.application_context_case.service;

import com.dwl.log.Logger;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

/**
 * @ClassName DynamicServiceConsumer
 * @Description <h2>动态服务消费者示例</h2>
 * <p>
 * <b>核心功能:</b>
 * <ul>
 *   <li>演示如何安全注入动态注册的Bean</li>
 *   <li>处理原型作用域Bean的延迟获取</li>
 *   <li>验证动态注册与依赖注入的协同工作</li>
 * </ul>
 * </p>
 *
 * <p>
 * <b>关键约束:</b>
 * <ul>
 *   <li>必须通过 {@link ObjectFactory} 延迟获取动态Bean</li>
 *   <li>需激活 {@code dynamic} Profile 才能生效</li>
 *   <li>禁止直接通过构造器注入动态Bean(因原型作用域特性)</li>
 * </ul>
 * </p>
 * @Version 1.0.0
 * @Date 2025
 * @Author By Dwl
 */
@Component
public class DynamicServiceConsumer {

    private final ObjectFactory<DynamicService> dynamicServiceFactory;


    /**
     * <h3>安全注入动态Bean</h3>
     * <p>
     * 使用 Spring 的 {@link ObjectFactory} 实现延迟获取:<br>
     * 1. 避免启动时强制初始化(兼容原型作用域)<br>
     * 2. 支持按需创建新实例<br>
     * 3. 自动处理依赖注入
     * </p>
     *
     * @param factory 动态Bean工厂(由Spring自动装配)
     */
    @Autowired
    public DynamicServiceConsumer(@Lazy ObjectFactory<DynamicService> factory) {
        this.dynamicServiceFactory = factory;
        Logger.debugF("DynamicServiceConsumer initialized with factory: {}", factory.hashCode());
    }

    /**
     * <h3>执行动态操作</h3>
     * <p>
     * <b>行为特征:</b>
     * <ul>
     *   <li>每次调用都会获取新实例(原型作用域)</li>
     *   <li>自动处理Bean不存在的情况</li>
     * </ul>
     * </p>
     */
    public void execute() {
        try {
            DynamicService service = dynamicServiceFactory.getObject();
            service.performDynamicAction();
            Logger.info("Dynamic action executed successfully");
        } catch (IllegalStateException e) {
            Logger.errorF("DynamicService registration failed: {}", e.getMessage());
        }
    }

    /**
     * <h3>验证动态注册状态</h3>
     * <p>
     * 调试方法:检查工厂是否包含有效Bean定义
     * </p>
     */
    public void validateRegistration() {
        dynamicServiceFactory.getObject();
        Logger.debug("DynamicService registration verified");
    }
}

LifecycleBean

package com.dwl.application_context_case.service;

import com.dwl.log.Logger;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.NonNull;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.stereotype.Component;

/**
 * 生命周期管理示例Bean
 * <p>
 * 该类演示Spring容器的完整Bean生命周期管理,包含:
 * 1. Bean元数据感知能力(名称/工厂)
 * 2. JSR-250标准生命周期方法
 * 3. Spring原生生命周期接口
 * 4. 初始化/销毁回调组合使用
 * </p>
 *
 * <p>
 * 生命周期执行顺序(简化版):
 * 1. setBeanName()
 * 2. setBeanFactory()
 * 3. @PostConstruct
 * 4. afterPropertiesSet()
 * 5. 自定义init-method
 * 6. @PreDestroy
 * 7. destroy()
 * </p>
 *
 * <p>
 * 日志策略:
 * - INFO级别:记录关键生命周期节点
 * - DEBUG级别:记录调试信息
 * - WARN级别:记录潜在问题
 * - ERROR级别:记录初始化失败
 * </p>
 *
 * @author By Dwl
 * @version 1.0.0
 * @see BeanNameAware
 * @see BeanFactoryAware
 * @see InitializingBean
 * @see DisposableBean
 * @since 2025
 */
@Component
public class LifecycleBean implements BeanNameAware, BeanFactoryAware,
        InitializingBean, DisposableBean {

    private String beanName;

    /**
     * 设置Bean名称
     * <p>
     * 生命周期阶段:实例化后立即执行
     * 执行顺序:优先于其他初始化方法
     * </p>
     *
     * @param name Spring容器分配的Bean名称
     */
    @Override
    public void setBeanName(@NonNull String name) {
        this.beanName = name;
        Logger.infoF("Bean名称已设置 - Name: {}, Class: {}", name, this.getClass().getSimpleName());
    }

    /**
     * 设置BeanFactory引用
     * <p>
     * 生命周期阶段:实例化后立即执行
     * 执行顺序:紧随setBeanName()
     * </p>
     *
     * @param factory 当前Bean所属的BeanFactory实例
     * @throws BeansException 如果设置失败
     */
    @Override
    public void setBeanFactory(BeanFactory factory) {
        Logger.debugF("BeanFactory引用已设置 - Factory ID: {}", factory.toString());
    }

    /**
     * JSR-250标准初始化方法
     * <p>
     * 生命周期阶段:属性设置完成后执行
     * 执行顺序:在afterPropertiesSet()之后
     * </p>
     *
     * @throws Exception 初始化失败时抛出异常
     * @see PostConstruct
     */
    @PostConstruct
    public void init() throws Exception {
        Logger.info("JSR-250初始化方法执行 - 开始");
        // 模拟初始化操作
        validateRequiredProperties();
        Logger.info("JSR-250初始化方法执行 - 完成");
    }

    /**
     * Spring原生初始化方法
     * <p>
     * 生命周期阶段:所有属性设置完成后执行
     * 执行顺序:在@PostConstruct之后
     * </p>
     */
    @Override
    public void afterPropertiesSet() {
        Logger.info("Spring初始化方法执行 - 开始");
        // 执行自定义初始化逻辑
        initializeResources();
        Logger.info("Spring初始化方法执行 - 完成");
    }

    /**
     * JSR-250标准销毁方法
     * <p>
     * 生命周期阶段:容器销毁前执行
     * 执行顺序:在destroy()之前
     * </p>
     *
     * @see PreDestroy
     */
    @PreDestroy
    public void destroyJsr250() {
        Logger.warn("JSR-250销毁方法执行 - 开始");
        cleanupResources();
        Logger.warn("JSR-250销毁方法执行 - 完成");
    }

    /**
     * Spring原生销毁方法
     * <p>
     * 生命周期阶段:容器销毁时最后执行
     * 执行顺序:在@PreDestroy之后
     * </p>
     */
    @Override
    public void destroy() {
        // 实际应选择一种实现方式,此处保留错误提示
        Logger.error("检测到重复的destroy方法定义!请保留其中一个实现");
    }

    // ----------------------
    // 内部辅助方法
    // ----------------------

    private void validateRequiredProperties() {
        // 实际应验证必要属性是否已设置
        if (beanName == null) {
            throw new IllegalStateException("Bean名称未正确设置");
        }
    }

    private void initializeResources() {
        // 实际应执行资源初始化操作
        Logger.debugF("正在初始化资源 - Bean名称: {}", beanName);
    }

    private void cleanupResources() {
        // 实际应执行资源清理操作
        Logger.debugF("正在清理资源 - Bean名称: {}", beanName);
    }
}

MyBean

package com.dwl.application_context_case.service;

import com.dwl.log.Logger;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;

/**
 * @ClassName MyBean
 * @Description <p>
 * 本类演示 Spring Bean 的初始化回调机制与事件发布能力,包含以下核心特性:
 * </p>
 * <ul>
 *   <li>通过 {@link InitializingBean} 接口实现属性初始化后的回调</li>
 *   <li>使用 {@link ApplicationEventPublisher} 实现自定义事件发布</li>
 *   <li>展示 Bean 生命周期中初始化阶段与业务逻辑的结合方式</li>
 * </ul>
 *
 * <p>
 * 典型应用场景:当 Bean 完成依赖注入后需要立即执行初始化逻辑,
 * 或需要与其他组件进行解耦的事件通信时使用
 * </p>
 * @Version 1.0.0
 * @Date 2025
 * @Author By Dwl
 */
@Component
public class MyBean implements InitializingBean {

    /**
     * Spring 事件发布器,用于发布自定义事件
     * <p>
     * 特性说明:
     * - 由 Spring 容器自动注入
     * - 实现 ApplicationEvent 发布的统一接口
     * - 支持发布任意类型的 ApplicationEvent 子类事件
     * </p>
     * <p>
     * 替代方案:可通过实现 {@link ApplicationEventPublisherAware} 接口获取
     * </p>
     */
    @Autowired
    private ApplicationEventPublisher publisher;

    /**
     * Spring Bean 初始化完成后的标准回调方法
     * <p>
     * 执行时机:
     * 1. 所有 @Autowired 依赖注入完成
     * 2. Bean 定义的所有属性设置完成
     * 3. 在 Bean 初始化流程的早期阶段执行(早于自定义 init-method)
     * </p>
     * <p>
     * 与 @PostConstruct 的区别:
     * - 本方法属于 Spring 框架接口回调
     * - @PostConstruct 属于 JSR-250 规范,优先级更高
     * - 两者执行顺序:@PostConstruct -> afterPropertiesSet
     * </p>
     */
    @Override
    public void afterPropertiesSet() {
        // 执行初始化完成后的业务逻辑
        Logger.info("【生命周期回调】MyBean 所有属性已初始化完成");

        // 示例:初始化完成后自动触发业务注册
        register(); // 根据实际需求决定是否在此处直接触发
    }

    /**
     * 自定义业务注册方法
     * <p>
     * 功能说明:
     * 1. 演示如何通过事件机制实现业务解耦
     * 2. 发布自定义的 MyRegisteredEvent 事件
     * 3. 事件携带当前 Bean 的引用作为事件源
     * </p>
     * <p>
     * 典型调用场景:
     * - 初始化完成后自动触发(通过 afterPropertiesSet 调用)
     * - 通过其他事件监听器间接触发
     * - 手动调用(需确保此时 Bean 已完成初始化)
     * </p>
     */
    public void register() {
        // 构造并发布自定义事件
        publisher.publishEvent(new MyRegisteredEvent(this));

        // 事件发布后执行的其他业务逻辑(如果有)
        Logger.info("【事件发布】已触发 MyRegisteredEvent 事件");
    }

    /**
     * 自定义事件类(需继承 ApplicationEvent)
     * <p>
     * 设计要点:
     * 1. 必须继承 ApplicationEvent 基类
     * 2. 通过构造函数传递事件源对象(即发布事件的 Bean)
     * 3. 包含事件相关的数据(可根据需求添加字段)
     * </p>
     * <p>
     * source 事件源对象(通常是发布事件的 Bean)
     */
    public static class MyRegisteredEvent extends ApplicationEvent {
        public MyRegisteredEvent(Object source) {
            super(source);
        }
    }
}

ProdAuditService

package com.dwl.application_context_case.service;

import com.dwl.application_context_case.config.DynamicBeanRegistrar;
import com.dwl.log.Logger;

/**
 * @ClassName ProdAuditService
 * @Description <h2>动态服务示例</h2>
 * <p>
 * <b>核心功能:</b>
 * <ul>
 *   <li>演示通过编程方式动态注册Bean</li>
 *   <li>验证BeanFactoryPostProcessor的使用</li>
 *   <li>展示原型作用域(Prototype Scope)行为</li>
 * </ul>
 * </p>
 *
 * <p>
 * <b>关键约束:</b>
 * <ul>
 *   <li>必须移除 {@code @Service} 注解(否则会与动态注册冲突)</li>
 *   <li>只能通过 {@link DynamicBeanRegistrar} 注册到容器</li>
 *   <li>需激活 {@code dynamic} Profile 才能生效</li>
 * </ul>
 * </p>
 *
 * <p>
 * <b>使用示例:</b>
 * <pre>
 * {@code
 * // 在需要使用的位置注入(需确保Profile激活)
 * @Autowired(required = false)
 * private DynamicService dynamicService;
 *
 * if (dynamicService != null) {
 *     dynamicService.performDynamicAction();
 * }
 * }
 * </pre>
 * </p>
 * @Version 1.0.0
 * @Date 2025
 * @Author By Dwl
 */
public class ProdAuditService {

    /**
     * 执行动态操作
     * <p>
     * <b>行为特征:</b>
     * <ul>
     <li>每次调用都会记录独立日志(因原型作用域每次创建新实例)</li>
     <li>无状态服务(不依赖成员变量)</li>
     </ul>
     */
    public void performDynamicAction() {
        Logger.info("[DynamicService] 执行动态操作 - 实例ID: " + this.hashCode());
    }

}