Spring IOC源码实现

一、Spring IOC实现原理

Spring IOC的核心实现类是org.springframework.beans.factory.BeanFactory和它的实现类org.springframework.context.ApplicationContext。最常用的是ClassPathXmlApplicationContextAnnotationConfigApplicationContext

主要流程:

  1. 资源定位:加载配置文件或注解,定位bean定义资源。
  2. 解析Bean定义:解析bean的配置信息,封装成BeanDefinition对象。
  3. 注册Bean定义:将BeanDefinition注册到BeanFactory的容器中。
  4. 实例化Bean:根据依赖关系实例化bean对象,处理依赖注入。
  5. 初始化Bean:执行初始化方法,如@PostConstructInitializingBean等。
  6. 使用Bean:通过getBean方法获取bean实例。

二、核心类介绍

  • BeanFactory:最基础的IOC容器接口,定义了getBean等方法。
  • ApplicationContext:扩展了BeanFactory,实现了更多功能,比如事件发布、国际化等。
  • DefaultListableBeanFactory:BeanFactory的核心实现类,负责bean的注册和实例化。
  • BeanDefinition:bean的元数据,描述bean的类型、作用域、依赖等信息。
  • BeanWrapper:用于包装bean对象,便于属性注入。

三、简化版IOC容器源码实现

下面是一个简化版的IOC容器实现,仅支持单例bean和构造器注入:

import java.util.HashMap;
import java.util.Map;

// Bean定义
class BeanDefinition {
    private Class<?> beanClass;
    public BeanDefinition(Class<?> beanClass) {
        this.beanClass = beanClass;
    }
    public Class<?> getBeanClass() {
        return beanClass;
    }
}

// 简易IOC容器
class SimpleIOC {
    private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();
    private Map<String, Object> singletonBeans = new HashMap<>();

    // 注册Bean定义
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(beanName, beanDefinition);
    }

    // 获取Bean实例
    public Object getBean(String beanName) throws Exception {
        Object bean = singletonBeans.get(beanName);
        if (bean != null) {
            return bean;
        }
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        if (beanDefinition == null) {
            throw new Exception("No bean named " + beanName);
        }
        // 实例化bean(这里只支持无参构造器)
        bean = beanDefinition.getBeanClass().getDeclaredConstructor().newInstance();
        singletonBeans.put(beanName, bean);
        return bean;
    }
}

// 测试用Bean
class UserService {
    public void sayHello() {
        System.out.println("Hello, Spring IOC!");
    }
}

// 测试
public class Main {
    public static void main(String[] args) throws Exception {
        SimpleIOC ioc = new SimpleIOC();
        ioc.registerBeanDefinition("userService", new BeanDefinition(UserService.class));
        UserService userService = (UserService) ioc.getBean("userService");
        userService.sayHello();
    }
}

四、Spring源码入口

如果你想深入学习Spring IOC源码,可以从以下类开始阅读:

  • DefaultListableBeanFactory.java(bean注册和实例化)
  • AbstractApplicationContext.java(容器初始化流程)
  • BeanDefinition.java(bean元数据)

五、源码深入讲解

1. BeanDefinition 注册与存储

Spring 在启动时,会将所有 bean 的配置信息(无论是 XML 还是注解)解析为 BeanDefinition 对象。BeanDefinition 记录了 bean 的类型、作用域、依赖、构造方法等元数据。

核心类

  • BeanDefinition
  • DefaultListableBeanFactory(实现了 BeanDefinitionRegistry 接口)

源码片段:

// BeanDefinitionRegistry.java
public interface BeanDefinitionRegistry {
    void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
        throws BeanDefinitionStoreException;
    // ... 其他方法
}

// DefaultListableBeanFactory.java
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
    this.beanDefinitionMap.put(beanName, beanDefinition);
}

2. Bean 的实例化和依赖注入

Spring IOC 最核心的功能就是实例化 Bean 并自动进行依赖注入。Spring 支持多种注入方式(构造器、setter、字段注入等)。

核心方法

  • AbstractAutowireCapableBeanFactory#createBean
  • doCreateBeanpopulateBeaninitializeBean

源码简化流程:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) {
    // 1. 实例化 Bean
    Object beanInstance = instantiateBean(beanName, mbd, args);

    // 2. 属性填充(依赖注入)
    populateBean(beanName, mbd, instanceWrapper);

    // 3. 初始化 Bean
    bean = initializeBean(beanName, bean, mbd);

    return bean;
}

3. Bean 生命周期管理

Spring 会在 Bean 实例化后,执行各种生命周期回调,比如:

  • BeanPostProcessor(前后置处理)
  • InitializingBeanDisposableBean
  • @PostConstruct@PreDestroy

源码片段:

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    // 1. 执行 BeanPostProcessor.beforeInitialization
    Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);

    // 2. 执行初始化方法(如 InitializingBean、@PostConstruct)
    invokeInitMethods(beanName, wrappedBean, mbd);

    // 3. 执行 BeanPostProcessor.afterInitialization
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

    return wrappedBean;
}

4. getBean 的实现

当我们调用 getBean("beanName") 时,Spring 会:

  1. 检查是否已经创建(单例缓存)
  2. 如果没有,则走完整的创建流程(如上)
  3. 返回最终的 Bean 实例

源码简化:

public Object getBean(String name) throws BeansException {
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null) {
        return getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
    // ... 如果没有,则创建
    Object bean = doCreateBean(beanName, mbd, args);
    return getObjectForBeanInstance(bean, name, beanName, mbd);
}

5. 简单模拟依赖注入(构造器注入)

下面我们扩展前面的 SimpleIOC,实现构造器参数注入:

class SimpleIOC {
    private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();
    private Map<String, Object> singletonBeans = new HashMap<>();

    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(beanName, beanDefinition);
    }

    public Object getBean(String beanName) throws Exception {
        Object bean = singletonBeans.get(beanName);
        if (bean != null) return bean;

        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        if (beanDefinition == null) throw new Exception("No bean named " + beanName);

        // 构造器注入
        Class<?> clazz = beanDefinition.getBeanClass();
        Constructor<?>[] constructors = clazz.getConstructors();
        for (Constructor<?> ctor : constructors) {
            Class<?>[] paramTypes = ctor.getParameterTypes();
            if (paramTypes.length == 0) {
                bean = ctor.newInstance();
                break;
            } else {
                Object[] params = new Object[paramTypes.length];
                for (int i = 0; i < paramTypes.length; i++) {
                    // 假定参数名和 beanName 一致
                    params[i] = getBean(paramTypes[i].getSimpleName());
                }
                bean = ctor.newInstance(params);
                break;
            }
        }
        singletonBeans.put(beanName, bean);
        return bean;
    }
}

6. Spring IOC 源码阅读建议

  • 从 ApplicationContext 入手,跟踪 refresh() 方法
  • 重点关注 DefaultListableBeanFactoryAbstractAutowireCapableBeanFactory
  • 理解 BeanDefinition、BeanFactory、BeanPostProcessor 的关系

7. 总结

Spring IOC 实现的核心就是:

  • Bean 定义的加载和注册
  • Bean 的实例化和依赖注入
  • Bean 的生命周期管理
  • Bean 的获取和缓存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猩火燎猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值