手写模拟Spring底层原理-Bean的创建与获取
字数 1196 2025-08-11 08:35:47

手写模拟Spring底层原理:Bean的创建与获取

1. 引言

本教学文档将详细讲解如何手动实现Spring框架的核心功能,包括Bean的创建与获取机制。通过这个简易版本的实现,我们可以深入理解Spring的底层原理。

2. 核心组件设计

2.1 主要类结构

  • JdApplicationContext: Spring启动类,实现bean的加载和获取功能
  • UserService/OrderService: Bean的实现类
  • App: 启动测试类
  • AppConfig: 启动配置类

2.2 核心注解

  • @Component: 标识需要创建Bean的类
  • @Autowired: 用于依赖注入
  • @Scope: 定义Bean的作用域(单例/原型)

3. 实现步骤详解

3.1 启动流程

  1. 初始化入口:
// App类作为入口
public class App {
    public static void main(String[] args) {
        JdApplicationContext context = new JdApplicationContext(AppConfig.class);
        UserService userService = (UserService) context.getBean("userService");
        userService.test();
    }
}
  1. JdApplicationContext构造函数:
public JdApplicationContext(Class<?> configClass) {
    // 1. 扫描配置类指定的包路径
    // 2. 创建并缓存BeanDefinition
    // 3. 初始化单例Bean
}

3.2 BeanDefinition的创建与缓存

  1. 扫描类路径:

    • 通过AppConfig配置类获取扫描路径
    • 查找带有@Component注解的类
  2. 创建BeanDefinition:

public class BeanDefinition {
    private Class<?> clazz;  // Bean类
    private String beanName;  // Bean名称
    private String scope;     // 作用域(singleton/prototype)
    // getter/setter方法
}
  1. 缓存到beanDefinitionMap:
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();

3.3 Bean的初始化与依赖注入

  1. 初始化流程:
private Object createBean(String beanName, BeanDefinition beanDefinition) {
    // 1. 通过反射实例化对象
    Class<?> clazz = beanDefinition.getClazz();
    Object instance = clazz.newInstance();
    
    // 2. 依赖注入(处理@Autowired注解)
    for (Field field : clazz.getDeclaredFields()) {
        if (field.isAnnotationPresent(Autowired.class)) {
            String fieldBeanName = field.getAnnotation(Autowired.class).value();
            if (fieldBeanName.isEmpty()) {
                fieldBeanName = field.getName();
            }
            Object fieldBean = getBean(fieldBeanName);
            field.setAccessible(true);
            field.set(instance, fieldBean);
        }
    }
    
    // 3. 初始化回调(处理InitializingBean接口)
    if (instance instanceof InitializingBean) {
        ((InitializingBean) instance).afterPropertiesSet();
    }
    
    return instance;
}
  1. getBean方法实现:
public Object getBean(String beanName) {
    BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
    if (beanDefinition == null) {
        throw new RuntimeException("No bean named " + beanName);
    }
    
    if ("prototype".equals(beanDefinition.getScope())) {
        // 原型模式每次都创建新实例
        return createBean(beanName, beanDefinition);
    } else {
        // 单例模式从缓存获取
        Object bean = singletonBeanMap.get(beanName);
        if (bean == null) {
            bean = createBean(beanName, beanDefinition);
            singletonBeanMap.put(beanName, bean);
        }
        return bean;
    }
}

3.4 循环依赖解决方案

  1. 问题描述:
// UserService
@Component
public class UserService {
    @Autowired
    private OrderService orderService;
}

// OrderService
@Component
public class OrderService {
    @Autowired
    private UserService userService;
}
  1. 二级缓存方案:
private final Map<String, Object> singletonBeanMap = new ConcurrentHashMap<>(); // 一级缓存
private final Map<String, Object> creatingBeanMap = new ConcurrentHashMap<>();  // 二级缓存

public Object getBean(String beanName) {
    // 检查一级缓存
    Object singleton = singletonBeanMap.get(beanName);
    if (singleton != null) return singleton;
    
    // 检查二级缓存(正在创建中的Bean)
    Object creatingBean = creatingBeanMap.get(beanName);
    if (creatingBean != null) return creatingBean;
    
    // 创建新实例
    BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
    if (beanDefinition == null) throw new RuntimeException("No bean named " + beanName);
    
    // 标记为正在创建
    Object bean = createBean(beanName, beanDefinition);
    creatingBeanMap.put(beanName, bean);
    
    // 完成创建后移入一级缓存
    if ("singleton".equals(beanDefinition.getScope())) {
        singletonBeanMap.put(beanName, bean);
        creatingBeanMap.remove(beanName);
    }
    
    return bean;
}

3.5 扩展点实现

  1. InitializingBean接口:
public interface InitializingBean {
    void afterPropertiesSet() throws Exception;
}
  1. BeanPostProcessor接口(模拟AOP):
public interface BeanPostProcessor {
    default Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }
    
    default Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
}
  1. AOP实现示例:
@Component
public class AopBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        if (bean instanceof UserService) {
            // 创建代理对象
            return Proxy.newProxyInstance(
                bean.getClass().getClassLoader(),
                bean.getClass().getInterfaces(),
                (proxy, method, args) -> {
                    System.out.println("AOP before...");
                    Object result = method.invoke(bean, args);
                    System.out.println("AOP after...");
                    return result;
                });
        }
        return bean;
    }
}

4. 完整流程总结

  1. 启动阶段:

    • 扫描配置类指定的包路径
    • 识别@Component注解的类并创建BeanDefinition
    • 缓存BeanDefinition到beanDefinitionMap
    • 识别并缓存BeanPostProcessor实现类
  2. Bean获取阶段:

    • 检查一级缓存(singletonBeanMap)
    • 检查二级缓存(creatingBeanMap)
    • 创建新实例(反射)
    • 依赖注入(处理@Autowired)
    • 执行BeanPostProcessor前置处理
    • 执行InitializingBean.afterPropertiesSet()
    • 执行BeanPostProcessor后置处理
    • 缓存单例Bean
  3. 扩展机制:

    • InitializingBean: 属性设置后的回调
    • BeanPostProcessor: Bean初始化前后的处理点

5. 进一步扩展方向

  1. 实现BeanFactory接口体系
  2. 添加@Lazy延迟加载支持
  3. 完善AOP切面表达式匹配
  4. 实现@Configuration配置类支持
  5. 添加Bean生命周期回调(@PostConstruct/@PreDestroy)

通过这个简易实现,我们深入理解了Spring的核心机制,包括Bean的创建、依赖注入、循环依赖解决和扩展点设计等关键概念。

手写模拟Spring底层原理:Bean的创建与获取 1. 引言 本教学文档将详细讲解如何手动实现Spring框架的核心功能,包括Bean的创建与获取机制。通过这个简易版本的实现,我们可以深入理解Spring的底层原理。 2. 核心组件设计 2.1 主要类结构 JdApplicationContext : Spring启动类,实现bean的加载和获取功能 UserService/OrderService : Bean的实现类 App : 启动测试类 AppConfig : 启动配置类 2.2 核心注解 @Component : 标识需要创建Bean的类 @Autowired : 用于依赖注入 @Scope : 定义Bean的作用域(单例/原型) 3. 实现步骤详解 3.1 启动流程 初始化入口 : JdApplicationContext构造函数 : 3.2 BeanDefinition的创建与缓存 扫描类路径 : 通过AppConfig配置类获取扫描路径 查找带有 @Component 注解的类 创建BeanDefinition : 缓存到beanDefinitionMap : 3.3 Bean的初始化与依赖注入 初始化流程 : getBean方法实现 : 3.4 循环依赖解决方案 问题描述 : 二级缓存方案 : 3.5 扩展点实现 InitializingBean接口 : BeanPostProcessor接口(模拟AOP) : AOP实现示例 : 4. 完整流程总结 启动阶段 : 扫描配置类指定的包路径 识别 @Component 注解的类并创建BeanDefinition 缓存BeanDefinition到beanDefinitionMap 识别并缓存BeanPostProcessor实现类 Bean获取阶段 : 检查一级缓存(singletonBeanMap) 检查二级缓存(creatingBeanMap) 创建新实例(反射) 依赖注入(处理@Autowired) 执行BeanPostProcessor前置处理 执行InitializingBean.afterPropertiesSet() 执行BeanPostProcessor后置处理 缓存单例Bean 扩展机制 : InitializingBean: 属性设置后的回调 BeanPostProcessor: Bean初始化前后的处理点 5. 进一步扩展方向 实现BeanFactory接口体系 添加@Lazy延迟加载支持 完善AOP切面表达式匹配 实现@Configuration配置类支持 添加Bean生命周期回调(@PostConstruct/@PreDestroy) 通过这个简易实现,我们深入理解了Spring的核心机制,包括Bean的创建、依赖注入、循环依赖解决和扩展点设计等关键概念。