Spring的IOC源码解读

Spring容器的初始化

核心方法: AbstractApplicationContext.refresh()
该方法使用了模板方法设计模式,核心步骤:
  1. prepareRefresh():准备上下文(如切换为启动、处理日志、环境变量校验、初始化监听器与事件)。
  2. obtainFreshBeanFactory():生成BeanFactory,生成、初始化BeanDefinitionReader、注册BeanDefinition(核心步骤)。
  3. prepareBeanFactory():配置 BeanFactory(如 ClassLoader、PostProcessor)、注册环境Bean。
  4. postProcessBeanFactory():子类扩展点(如 WebApplicationContext)。
  5. invokeBeanFactoryPostProcessors():处理 BeanFactoryPostProcessor。
  6. registerBeanPostProcessors():注册 BeanPostProcessor。
  7. initMessageSource():国际化支持。
  8. initApplicationEventMulticaster():事件广播器。
  9. onRefresh():子类扩展点(如 ServletWebServerApplicationContext 启动内嵌 Tomcat)。
  10. registerListeners():注册事件监听器。
  11. finishBeanFactoryInitialization():初始化所有单例 Bean(核心步骤)。
  12. finishRefresh():发布 ContextRefreshedEvent 事件。

比较重要的类

AbstractApplicationContext :实现了应用程序上下文对象(DI容器)的初始化。
BeanFactory
  • 定义:创建、配置、初始化、依赖注入、销毁Bean对象。
  • 子类:DefaultListableBeanFactory(管理 Bean 定义和实例化流程)、AbstractAutowireCapableBeanFactory(实现 Bean 的创建、依赖注入和初始化)。
BeanDefinitionReader
  • 定义:读取和解析Bean定义。
  • 子类:XmlBeanDefinitionReader(解析 XML)、AnnotatedBeanDefinitionReader(解析注解)、ClassPathBeanDefinitionScanner(扫描类路径)。
BeanDefinition:描述与管理Bean定义信息。
ResourceLoader
  • 定义:用于加载资源。
  • 子类:ClassPathResource(类路径资源)、FileSystemResource(文件系统资源)。

Bean的生命周期

1. Bean的实例化前的准备阶段

  • 目标:生成Bean实例化所需要的BeanFactory、BeanDefinitionReader、BeanDefinition等类找到 Bean 的配置信息(XML、注解、Java Config 等)。
  • 源码入口:容器初始化的第二步骤。
    • 生成BeanFactory。
    • BeanFactory(本身DefaultListableBeanFactory实现了BeanDefinitionRegistry)装配BeanDefinitionReader
    • BeanDefinitionReader中装配ResourceLoader。
    • ResourceLoader加载读取配置信息(XML、注解、Java Config 等)并注册BeanDefinition到BeanDefinitionRegistry的beanDefinitionMap中,以bean名称为键的BeanDefinition对象映射表。
如:AbstractXmlApplicationContext.loadBeanDefinitions(DefaultListableBeanFactory beanFactory)。
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
   // Create a new XmlBeanDefinitionReader for the given BeanFactory.
   XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

   // Configure the bean definition reader with this context's
   // resource loading environment.
   beanDefinitionReader.setEnvironment(this.getEnvironment());
   beanDefinitionReader.setResourceLoader(this);
   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

   // Allow a subclass to provide custom initialization of the reader,
   // then proceed with actually loading the bean definitions.
   initBeanDefinitionReader(beanDefinitionReader);
   loadBeanDefinitions(beanDefinitionReader);
}

注册过程:DefaultListableBeanFactory.registerBeanDefinition()。

// 注册 BeanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);

2. 实例化前的BeanFactoryPostProcessor 处理

  • 目标:在 Bean 实例化前修改 BeanDefinition。
  • 源码入口:容器初始化的第五步骤。BeanFactoryPostProcessor.postProcessBeanFactory()。
    • 触发时机:在 AbstractApplicationContext.refresh() 的 invokeBeanFactoryPostProcessors() 阶段。
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let the bean factory post-processors apply to them!
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);  
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);    
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);           
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);                      
}

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

   for (BeanFactoryPostProcessor postProcessor : postProcessors) {
      StartupStep postProcessBeanFactory = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process")
            .tag("postProcessor", postProcessor::toString);
      postProcessor.postProcessBeanFactory(beanFactory);
      postProcessBeanFactory.end();
   }
}  

3. 注册BeanPostProcessor

  • 源码入口:容器初始化的第6步骤。

4. Bean 实例化(Instantiation)

  • 目标:通过反射或工厂方法创建 Bean 实例。
  • 源码入口:容器初始化的第11步骤。AbstractAutowireCapableBeanFactory.createBean()。
    • 关键方法:doCreateBean() -> createBeanInstance()。
    • 策略:使用 InstantiationStrategy(默认 CglibSubclassingInstantiationStrategy)。
getInstantiationStrategy().instantiate(mbd, beanName, this)

5. 依赖注入(Dependency Injection)属性赋值

  • 目标:注入 Bean 的属性和依赖。
  • 源码入口:AbstractAutowireCapableBeanFactory.populateBean()。
    • 策略:
      • 字段注入:通过反射直接设置字段(@Autowired)。
      • Setter 注入:调用 Setter 方法。
      • 构造器注入:通过构造器参数解析(ConstructorResolver)。
    • 关键类:AutowiredAnnotationBeanPostProcessor(处理 @Autowired 和 @Value)。
// 示例:注入依赖
for (BeanPostProcessor bp : getBeanPostProcessors()) {
    if (bp instanceof InstantiationAwareBeanPostProcessor) {
        // 处理 @Autowired 等注解
        ((InstantiationAwareBeanPostProcessor) bp).postProcessProperties(pvs, bean, beanName);
    }
}

6. 初始化(Initialization)

  • 目标:调用初始化方法。
  • 源码入口:AbstractAutowireCapableBeanFactory.initializeBean()。
    • 步骤:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    // 1. 调用 Aware 接口(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware)
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    } else {
        invokeAwareMethods(beanName, bean); // 直接调用 Aware 方法
    }

    // 2. 执行 BeanPostProcessor 的前置处理(包括其他 Aware 接口)
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    // 3. 调用 InitializingBean.afterPropertiesSet() 和 init-method
    // ...
    return wrappedBean;
}

// 示例:初始化前后的处理
public Object applyBeanPostProcessorsBeforeInitialization(Object bean, String beanName) {
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        bean = processor.postProcessBeforeInitialization(bean, beanName);
    }
    return bean;
}

// 示例:调用初始化方法
if (bean instanceof InitializingBean) {
    ((InitializingBean) bean).afterPropertiesSet();
}

7. Bean 的销毁(Destruction)

  • 目标:容器关闭时销毁 Bean。
  • 源码入口:DisposableBeanAdapter.destroy()。
    • 触发方式:
      • 实现 DisposableBean 接口的 destroy()。
      • 配置 destroy-method。
    • 关键逻辑:在 AbstractApplicationContext.close() 中调用 destroyBeans()。
// 示例:销毁 Bean
if (bean instanceof DisposableBean) {
    ((DisposableBean) bean).destroy();
}

关键点总结

1. 触发时机

  • 单例非懒加载 Bean 的实例化在容器启动时完成(refresh() 的 finishBeanFactoryInitialization() 阶段)。
  • 原型(Prototype)或懒加载(Lazy-init)的 Bean 在首次getBean() 调用时实例化。

2. 实例化与初始化的区别

  • 实例化(Instantiation):创建 Bean 对象(调用构造器)。
  • 初始化(Initialization):填充属性、执行 @PostConstruct、实现InitializingBean接口的afterPropertiesSet() 等逻辑。

流程图解

AbstractApplicationContext.finishBeanFactoryInitialization(beanFactory)
    └─> beanFactory.preInstantiateSingletons()
        └─> DefaultListableBeanFactory.preInstantiateSingletons()
            └─> AbstractBeanFactory.getBean(beanName)
                └─> doGetBean(name, null, null, false)
                    └─> createBean(beanName, mbd, args)
                        └─> AbstractAutowireCapableBeanFactory.createBean(beanName, mbd, args)
                            └─> doCreateBean(beanName, mbdToUse, args)
                                └─> createBeanInstance(beanName, mbd, args) // 实例化
                                    └─> instantiateBean(beanName, mbd)
                                        └─> getInstantiationStrategy().instantiate(mbd, beanName, this)
                                └─> populateBean(beanName, mbd, instanceWrapper)    // 依赖注入
                                └─> initializeBean(beanName, exposedObject, mbd)    // 初始化
                                    └─> invokeAwareMethods(beanName, bean) // aware接口,基础设施引用
                                    └─> applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)    // bean前置处理器
                                    └─> invokeInitMethods(beanName, wrappedBean, mbd) // 调用初始化方法
                                        └─> ((InitializingBean) bean).afterPropertiesSet() // 调用设置属性后方法
                                        └─> invokeCustomInitMethod(beanName, bean, mbd) // 调用自定义初始化方法
                                    └─> applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)    // bean后置处理器
                                 └─> registerDisposableBeanIfNecessary(beanName, bean, mbd)    // 注册需要销毁的bean的方法

Bean的相关应用

1、实例化Bean之前,对bean定义进行扩展或者修改

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 在这里可以修改 bean 的定义,例如:
        // 获取到某个 bean 的定义并修改它
        BeanDefinition bd = beanFactory.getBeanDefinition("myBean");
        bd.getPropertyValues().addPropertyValue("brand", "问界");
        System.out.println("BeanFactoryPostProcessor is called");
    }

}

2、实例化后,初始化方法前后的处理

public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 在初始化方法之前执行的逻辑
        System.out.println("Before initialization: " + beanName);
        return bean; // 返回bean对象,以便继续后续的初始化过程
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 在初始化方法之后执行的逻辑
        System.out.println("After initialization: " + beanName);
        return bean; // 返回bean对象,以便继续后续的流程
    }

}

3、实例化后,初始化方法

xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- @PostConstruct 需要启动注解 -->
    <context:annotation-config />

    <!-- 注册myBean的bean,并设置init-method方法 -->
    <bean id="myBean" class="org.example.MyBean" init-method="initMethod">
        <!-- 设置依赖注入的属性 -->
        <property name="message" value="Hello, Spring!" />
    </bean>

</beans>

bean的实现

public class MyBean implements InitializingBean {

    private String message;


    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @PostConstruct
    public void initPostConstruct() {
        System.out.println("执行MyBean的PostConstruct...");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("执行MyBean的初始化方法");
    }

    //在配置类中利用注解将initMethod指向下面的init方法-对应于initMethod的用法
    public void initMethod() {
        System.out.println("执行MyBean的init-method...");
    }
    
    @PreDestroy
    public void destroy() {
        // 销毁逻辑
        System.out.println("执行MyBean的销毁方法");
    }
    
    // 在配置类中利用注解将destroy-method指向下面的destoryMethod
    public void destoryMethod() {
        System.out.println("执行MyBean的destory-method...");
    }
}
执行顺序@PostConstruct -> afterPropertiesSet() -> initMethod()

4、Bean的销毁

xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- @PostConstruct 需要启动注解 -->
    <context:annotation-config />

    <!-- 注册myBean的bean,并设置init-method方法 -->
    <bean id="myBean" class="org.example.MyBean" destroy-method="destoryMethod">
        <!-- 设置依赖注入的属性 -->
        <property name="message" value="Hello, Spring!" />
    </bean>

</beans>

bean的实现

public class MyBean implements InitializingBean {

    private String message;


    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
    
    @PreDestroy
    public void destroy() {
        // 销毁逻辑
        System.out.println("执行MyBean的销毁方法");
    }
    
    // 在配置类中利用注解将destroy-method指向下面的destoryMethod
    public void destoryMethod() {
        System.out.println("执行MyBean的destory-method...");
    }
}

执行顺序@PreDestroy->destoryMethod()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值