Files
blog-press/docs/Web-Backend/SpringBoot/SpringIOC.md
2025-12-16 18:07:42 +08:00

21 KiB
Raw Blame History

title, date
title date
Spring IOC简介 2025-11-26

一、IOC

Spring框架的核心是IOC控制反转容器它负责管理应用程序中的对象称为Bean的创建、配置和组装。

二、Bean

2.1 定义

在Spring中Bean是指由Spring IOC容器管理的对象实例。这些对象不再由应用程序直接创建而是由容器负责实例化、配置和组装。
  例如@Service、@Controller就是特殊的Bean。

2.2 特点

  • 由容器管理生命周期由Spring容器控制
  • 可配置性通过配置元数据定义Bean的行为
  • 依赖注入容器自动处理Bean之间的依赖关系
  • 作用域支持支持singleton、prototype等不同作用域

2.3 创建方式

// 1. 通过@Component注解
@Component
public class UserService {
    // ...
}

// 2. 通过@Bean注解配置类中
@Configuration
public class AppConfig {
    @Bean
    public DataSource dataSource() {
        return new DataSource();
    }
}

// 3. 通过XML配置
<bean id="userService" class="com.example.UserService"/>

2.4 作用域

  控制 Bean 在容器中的实例数量和生命周期。Spring 提供多种作用域,默认是 singleton。通过 @Scope 注解指定,如 @Scope("prototype")。

  • singleton单例容器中只有一个实例所有请求共享该实例默认值
  • prototype多例每次请求如 getBean())都会创建新实例,容器不管理其销毁。
  • requestWeb每个 HTTP 请求创建一个实例,仅在当前请求有效。
  • sessionWeb每个会话创建一个实例在会话有效期内有效。

2.5 生命周期

  1. 实例化Instantiation容器通过构造器创建 Bean 实例(分配内存)。
  2. 属性注入Population容器将依赖的 Bean 注入到当前 Bean 的字段或方法(如 @Autowired 标注的依赖)。
  3. 初始化前Post-processing before initialization 执行 BeanPostProcessor 的 postProcessBeforeInitialization 方法AOP 代理生成在此阶段)。
  4. 初始化Initialization 调用 @PostConstruct 注解的方法JSR-250 标准,推荐)。 若实现 InitializingBean 接口,调用 afterPropertiesSet() 方法。 执行自定义初始化方法(如 @Bean(initMethod = "init") 中指定的 init 方法)。
  5. 初始化后Post-processing after initialization 执行 BeanPostProcessor 的 postProcessAfterInitialization 方法。
  6. 使用In UseBean 被应用程序调用。
  7. 销毁Destruction 调用 @PreDestroy 注解的方法JSR-250 标准,推荐)。 若实现 DisposableBean 接口,调用 destroy() 方法。 执行自定义销毁方法(如 @Bean(destroyMethod = "destroy") 中指定的 destroy 方法)。

暂无图片

三、BeanDefinition

3.1 定义

BeanDefinition是Spring框架中描述Bean的元数据对象它包含了创建Bean实例所需的所有信息。

3.2 作用

  • 定义Bean的类名
  • 设置Bean的作用域
  • 配置Bean的属性值
  • 定义依赖关系
  • 配置初始化/销毁方法

3.3 结构

BeanDefinition (接口)
    ↑
AbstractBeanDefinition (抽象类)
    ↑
RootBeanDefinition, GenericBeanDefinition, ChildBeanDefinition

3.4 关键属性

public interface BeanDefinition {
    // Bean的类名
    void setBeanClassName(String beanClassName);
    String getBeanClassName();
    
    // 作用域singleton、prototype等
    void setScope(String scope);
    String getScope();
    
    // 是否延迟初始化
    void setLazyInit(boolean lazyInit);
    boolean isLazyInit();
    
    // 依赖的Bean名称
    void setDependsOn(String... dependsOn);
    String[] getDependsOn();
    
    // 初始化方法
    void setInitMethodName(String initMethodName);
    String getInitMethodName();
    
    // 销毁方法
    void setDestroyMethodName(String destroyMethodName);
    String getDestroyMethodName();
    
    // 工厂方法名
    void setFactoryMethodName(String factoryMethodName);
    String getFactoryMethodName();
}  

3.5 创建过程

// 编程方式创建BeanDefinition
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClassName("com.example.UserService");
beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
beanDefinition.setLazyInit(false);

// 注册到BeanFactory
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerBeanDefinition("userService", beanDefinition);

四、BeanFactory

4.1 定义

BeanFactory是Spring IOC容器的根接口提供了最基本的IOC功能。它是访问Spring容器的基本客户端视图。

4.2 结构

BeanFactory (根接口)
    ↑
ListableBeanFactory, HierarchicalBeanFactory, AutowireCapableBeanFactory
    ↑
ConfigurableBeanFactory, ConfigurableListableBeanFactory
    ↑
DefaultListableBeanFactory (主要实现类)

4.3 核心方法

public interface BeanFactory {
    // 根据名称获取Bean实例
    Object getBean(String name) throws BeansException;
    
    // 根据名称和类型获取Bean实例
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;
    
    // 根据类型获取Bean实例
    <T> T getBean(Class<T> requiredType) throws BeansException;
    
    // 判断是否包含指定名称的Bean
    boolean containsBean(String name);
    
    // 判断Bean是否是单例
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    
    // 判断Bean是否是原型
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
    
    // 获取Bean的类型
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;
}

4.4 实现示例

// 创建BeanFactory实例
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

// 创建BeanDefinition
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClassName("com.example.UserService");

// 注册BeanDefinition
beanFactory.registerBeanDefinition("userService", beanDefinition);

// 获取Bean实例
UserService userService = beanFactory.getBean("userService", UserService.class);

4.5 特点

  • 轻量级:功能相对简单,资源消耗少
  • 延迟加载默认在第一次请求时才创建Bean实例
  • 基础功能提供最基本的IOC功能

五、ApplicationContext

5.1 定义

ApplicationContext是BeanFactory的子接口在BeanFactory的基础上提供了更多企业级功能是Spring容器的完整实现。

5.2 结构

BeanFactory
    ↑
ApplicationContext (扩展接口)
    ↑
ConfigurableApplicationContext
    ↑
AbstractApplicationContext
    ↑
ClassPathXmlApplicationContext, FileSystemXmlApplicationContext, 
AnnotationConfigApplicationContext, WebApplicationContext

5.3 特点

  • 完整的IOC功能包含BeanFactory的所有功能
  • 预实例化单例Bean默认在启动时创建单例Bean
  • 企业级功能支持AOP、事务管理、国际化等
  • 资源访问:统一的资源访问接口
  • 事件机制:支持应用内事件发布/订阅

5.4 refresh方法

// AbstractApplicationContext.java
/**
 * Spring ApplicationContext 的核心启动方法
 * 定义了容器初始化的完整生命周期
 */
public void refresh() throws BeansException, IllegalStateException {
    // 使用同步锁确保容器启动的线程安全性,防止并发刷新
    synchronized (this.startupShutdownMonitor) {
        
        // [1] 准备刷新容器 - 设置启动状态,验证环境配置
        prepareRefresh();
        
        // [2] 获取或创建BeanFactory - 创建DefaultListableBeanFactory实例
        // 如果是XML配置会在这里加载和解析XML文件
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        
        // [3] 配置BeanFactory - 设置类加载器、注册核心BeanPostProcessor等
        prepareBeanFactory(beanFactory);
        
        try {
            // [4] 后处理BeanFactory - 模板方法,允许子类进行特殊配置
            // Web应用会在这里注册Servlet相关的Scope
            postProcessBeanFactory(beanFactory);
            
            // [5] 🚀 关键步骤调用BeanFactory后置处理器
            // 执行BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor
            // ConfigurationClassPostProcessor在这里扫描@Component、@Configuration等注解
            invokeBeanFactoryPostProcessors(beanFactory);
            
            // [6] 注册Bean后置处理器 - 注册所有BeanPostProcessor
            // 包括AOP、事务、自定义的BeanPostProcessor此时只是注册还未执行
            registerBeanPostProcessors(beanFactory);
            
            // [7] 初始化消息源 - 设置国际化消息资源
            // 用于支持多语言消息解析
            initMessageSource();
            
            // [8] 初始化应用事件广播器 - 创建事件发布机制的核心组件
            // 用于发布ApplicationEvent事件
            initApplicationEventMulticaster();
            
            // [9] 模板方法:子类可以在这里执行特殊的刷新逻辑
            // SpringBoot在这里启动内嵌的Tomcat服务器
            onRefresh();
            
            // [10] 注册监听器 - 将所有ApplicationListener注册到事件广播器
            // 包括静态指定的监听器和从BeanFactory中获取的监听器
            registerListeners();
            
            // [11] 🏭 核心步骤完成BeanFactory的初始化
            // 实例化所有非懒加载的单例Bean执行依赖注入、AOP代理等
            finishBeanFactoryInitialization(beanFactory);
            
            // [12] 完成刷新过程 - 发布ContextRefreshedEvent事件
            // 标记容器启动完成,可以正常工作了
            finishRefresh();
            
        } catch (BeansException ex) {
            // 如果刷新过程中出现异常需要销毁已经创建的单例Bean防止资源泄漏
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                           "cancelling refresh attempt: " + ex);
            }
            
            // 销毁已经创建的单例Bean
            destroyBeans();
            
            // 重置容器状态为未激活
            cancelRefresh(ex);
            
            // 重新抛出异常
            throw ex;
        } finally {
            // 最后重置一些公共的缓存,比如反射缓存
            resetCommonCaches();
        }
    }
}

5.4.1 prepareRefresh()

protected void prepareRefresh() {
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);
    
    if (logger.isInfoEnabled()) {
        logger.info("Refreshing " + this);
    }
    
    initPropertySources();
    getEnvironment().validateRequiredProperties();
    this.earlyApplicationEvents = new LinkedHashSet<>();
}
  • 这是容器启动的第一步,主要做初始化准备工作
  • 设置容器的启动时间戳和活跃状态
  • 验证必要的环境属性是否配置正确(比如通过@Value注解标记为必须的属性
  • 初始化早期事件集合,用于存储在事件多播器创建前发布的事件
  • 为整个刷新过程奠定基础状态

5.4.2 obtainFreshBeanFactory()

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory();
}

// 子类实现示例
protected final void refreshBeanFactory() throws IllegalStateException {
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        customizeBeanFactory(beanFactory);
        loadBeanDefinitions(beanFactory);
        this.beanFactory = beanFactory;
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error", ex);
    }
}
  • 创建或刷新底层的BeanFactorySpring容器的核心工厂
  • 如果是刷新操作会先销毁旧的BeanFactory和所有Bean实例
  • 创建新的DefaultListableBeanFactory实例
  • 加载Bean定义从XML文件或注解配置中解析Bean的元数据
  • 这个步骤完成后容器就知道了有哪些Bean需要管理但还没有创建Bean实例

5.4.3 prepareBeanFactory()

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    beanFactory.setBeanClassLoader(getClassLoader());
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);
}
  • 配置BeanFactory的基本设置和功能组件
  • 设置类加载器、SPEL表达式解析器、属性编辑器
  • 注册ApplicationContextAwareProcessor这是实现各种Aware接口的关键
  • 忽略某些接口的依赖注入(这些接口由容器特殊处理)
  • 注册可解析的依赖关系当Bean需要这些类型时直接返回容器实例
  • 为BeanFactory添加基本的功能支持

5.4.4 postProcessBeanFactory()

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 空方法 - 模板方法模式
    // 子类可以覆盖此方法添加特定逻辑
}
  • 模板方法允许子类在标准初始化后对BeanFactory进行自定义配置
  • 在Web环境中会在这里注册Servlet相关的Scoperequest、session等
  • 可以添加特定环境的BeanPostProcessor或进行其他特殊配置
  • 这是框架扩展的重要切入点

5.4.5 invokeBeanFactoryPostProcessors()

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}
  • 🚀 这是最关键的一步负责扫描和注册所有的Bean定义
  • 执行所有BeanFactoryPostProcessor它们可以修改Bean的定义信息
  • 特别是ConfigurationClassPostProcessor它负责 扫描@Component、@Service、@Repository等注解 处理@Configuration配置类 解析@Bean方法定义 处理@Import、@ComponentScan等注解
  • 这一步完成后所有的Bean定义都已经被解析和注册

5.4.6 registerBeanPostProcessors()

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
  • 注册所有的BeanPostProcessor到BeanFactory中
  • 包括AOP、事务管理、自定义的Bean后置处理器等
  • 注意此时只是注册真正的调用要等到Bean实例化时
  • 这些处理器按照优先级顺序注册,确保执行顺序正确
  • 这是Spring AOP和事务管理等高级功能的基础

5.4.7 initMessageSource()

protected void initMessageSource() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
        this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
    }
    else {
        DelegatingMessageSource dms = new DelegatingMessageSource();
        this.messageSource = dms;
        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
    }
}
  • 初始化国际化消息支持
  • 如果用户配置了自定义的MessageSource就使用用户的配置
  • 否则创建默认的DelegatingMessageSource
  • 支持从属性文件读取多语言消息,实现国际化功能
  • 用于解析${}占位符和国际化消息

5.4.8 initApplicationEventMulticaster()

protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
    }
    else {
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
    }
}
  • 初始化应用事件发布机制的核心组件
  • 如果用户配置了自定义的事件广播器,就使用用户的配置
  • 否则创建默认的SimpleApplicationEventMulticaster
  • 这个组件负责将应用事件广播给所有监听器
  • 支持观察者模式,实现应用内组件间的解耦通信

5.4.9 onRefresh() - 刷新时扩展点

protected void onRefresh() throws BeansException {
    // 空方法 - 模板方法
}
  • 模板方法,允许子类在特定时机执行自定义逻辑
  • 在Spring Boot中这里会启动内嵌的Web服务器Tomcat、Jetty等
  • 在Spring MVC中这里会初始化HandlerMapping、HandlerAdapter等组件
  • 这是框架扩展的重要切入点不同的ApplicationContext实现有不同的行为

5.4.10 registerListeners()

protected void registerListeners() {
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }
    
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }
    
    // 发布早期事件
    if (this.earlyApplicationEvents != null) {
        for (ApplicationEvent earlyEvent : this.earlyApplicationEvents) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}
  • 注册所有的事件监听器到事件广播器
  • 包括静态注册的监听器和从BeanFactory中获取的监听器Bean
  • 发布在监听器注册前收集的早期事件
  • 确保事件发布机制完整可用,应用事件能够正确分发

5.4.11 finishBeanFactoryInitialization()

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME)) {
        beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }
    
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }
    
    beanFactory.freezeConfiguration();
    beanFactory.preInstantiateSingletons();
}
  • 🏭 这是最核心的步骤真正创建Bean实例
  • 初始化类型转换服务ConversionService
  • 注册嵌入式值解析器(用于解析${}占位符)
  • 冻结Bean定义防止后续修改
  • 实例化所有非懒加载的单例Bean这个过程中会 创建Bean实例 执行依赖注入(@Autowired、@Resource等 执行BeanPostProcessorAOP代理在这里发生 调用初始化方法(@PostConstruct、InitializingBean
  • 这是容器启动过程中最耗时的步骤

5.4.12 finishRefresh()

protected void finishRefresh() {
    clearResourceCaches();
    initLifecycleProcessor();
    getLifecycleProcessor().onRefresh();
    publishEvent(new ContextRefreshedEvent(this));
    LiveBeansView.registerApplicationContext(this);
}
  • 完成容器的启动过程,进行最后的清理和通知工作
  • 清除资源缓存,释放临时资源
  • 初始化生命周期处理器管理Bean的生命周期
  • 发布ContextRefreshedEvent事件通知所有监听器容器已启动完成
  • 注册LiveBeansView用于监控和调试
  • 标记整个容器启动流程结束,容器进入就绪状态

5.4.13 总结

refresh()方法按固定顺序执行12个步骤核心可归纳为准备容器环境 → 解析并注册Bean定义→ 初始化事件、消息等基础设施 → 实例化所有非懒加载的单例Bean→ 完成启动并发布事件。整个过程通过模板方法模式定义,确保了扩展性和一致性。 核心在于两个关键扩展机制BeanFactoryPostProcessor在Bean定义阶段介入负责修改和注册Bean的定义信息BeanPostProcessor在Bean实例化阶段介入负责对创建好的Bean实例进行增强和包装。