手写Spring框架(简朴实现)

[复制链接]
发表于 2026-2-1 07:08:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
Spring风格的三级缓存管理:一个简朴实现示例

在实现一个简朴的Spring风格的依赖注入容器时,我们通常必要处理处罚Bean的生命周期,包罗实例化、属性注入以及完全初始化。为了处理处罚复杂的依赖关系和循环依赖题目,我们可以使用三级缓存机制。本文将先容怎样实现这种机制,并展示相应的代码示例。
三级缓存的概念


  • 一级缓存(singletonObjects):存储完全初始化的单例Bean。
  • 二级缓存(earlySingletonObjects):存储实例化但尚未完成全部属性注入的Bean。
  • 三级缓存(singletonFactories):存储Bean工厂,用于延长初始化息争决循环依赖。
完备的实当代码

以下是一个实现三级缓存的简朴容器的代码示例。这个实现使用了dom4j库来剖析XML设置文件,创建和管理Bean的生命周期。
  1. package org.xtl.spring;
  2. import org.dom4j.*;
  3. import org.dom4j.io.SAXReader;
  4. import java.io.InputStream;
  5. import java.lang.reflect.Constructor;
  6. import java.lang.reflect.Method;
  7. import java.util.HashMap;
  8. import java.util.List;
  9. import java.util.Map;
  10. /**
  11. * ClassPathXmlApplicationContext 实现了一个简单的 Spring 风格的依赖注入容器。
  12. * 它使用三级缓存来处理 Bean 的创建和依赖注入,以支持复杂的依赖关系和循环依赖。
  13. */
  14. public class ClassPathXmlApplicationContext implements ApplicationContext {
  15.     // 一级缓存:存放完全初始化的单例 Bean
  16.     private final Map<String, Object> singletonObjects = new HashMap<>();
  17.    
  18.     // 二级缓存:存放实例化但未完成所有属性注入的单例 Bean
  19.     private final Map<String, Object> earlySingletonObjects = new HashMap<>();
  20.    
  21.     // 三级缓存:存放 Bean 工厂,用于延迟初始化和解决循环依赖
  22.     private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>();
  23.     /**
  24.      * 构造函数,加载配置文件并初始化 Bean。
  25.      *
  26.      * @param configLocation 配置文件的位置
  27.      */
  28.     public ClassPathXmlApplicationContext(String configLocation) {
  29.         try {
  30.             // 读取配置文件
  31.             InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(configLocation);
  32.             SAXReader reader = new SAXReader();
  33.             Document document = reader.read(is);
  34.             Element root = document.getRootElement();
  35.             List<Element> beanElements = root.elements("bean");
  36.             // 第一次遍历:实例化 Bean 并将 Bean 工厂放入三级缓存
  37.             for (Element beanEle : beanElements) {
  38.                 String id = beanEle.attributeValue("id");
  39.                 String className = beanEle.attributeValue("class");
  40.                 Class<?> clazz = Class.forName(className);
  41.                 Constructor<?> constructor = clazz.getDeclaredConstructor();
  42.                 constructor.setAccessible(true);
  43.                 // 使用 ObjectFactory 创建 Bean 实例
  44.                 ObjectFactory<?> singletonFactory = () -> {
  45.                     try {
  46.                         return constructor.newInstance();
  47.                     } catch (Exception e) {
  48.                         throw new RuntimeException("Failed to create bean instance", e);
  49.                     }
  50.                 };
  51.                 // 将工厂放入三级缓存
  52.                 singletonFactories.put(id, singletonFactory);
  53.             }
  54.             // 第二次遍历:进行属性填充和依赖注入
  55.             for (Element beanEle : beanElements) {
  56.                 String id = beanEle.attributeValue("id");
  57.                 Class<?> clazz = Class.forName(beanEle.attributeValue("class"));
  58.                
  59.                 // 从三级缓存获取 Bean 实例并将其放入 earlySingletonObjects
  60.                 Object bean = getSingleton(id);
  61.                
  62.                 List<Element> propertyEles = beanEle.elements("property");
  63.                 for (Element propertyEle : propertyEles) {
  64.                     String propertyName = propertyEle.attributeValue("name");
  65.                     String propertyValueStr = propertyEle.attributeValue("value");
  66.                     String propertyRefStr = propertyEle.attributeValue("ref");
  67.                     Object propertyValue = null;
  68.                     // 获取属性类型
  69.                     Class<?> propertyType = clazz.getDeclaredField(propertyName).getType();
  70.                     if (propertyValueStr != null) {
  71.                         // 将属性值转换为正确的类型
  72.                         propertyValue = changeType(propertyType.getSimpleName(), propertyValueStr);
  73.                     }
  74.                     if (propertyRefStr != null) {
  75.                         // 从 earlySingletonObjects 中获取属性值
  76.                         propertyValue = earlySingletonObjects.get(propertyRefStr);
  77.                     }
  78.                     // 设置属性
  79.                     String methodName = "set" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
  80.                     Method method = clazz.getDeclaredMethod(methodName, propertyType);
  81.                     method.setAccessible(true);
  82.                     method.invoke(bean, propertyValue);
  83.                 }
  84.                 // 将完全初始化的 Bean 放入一级缓存,并从二级缓存中移除
  85.                 singletonObjects.put(id, bean);
  86.                 earlySingletonObjects.remove(id);
  87.                 singletonFactories.remove(id);
  88.             }
  89.         } catch (Exception e) {
  90.             throw new RuntimeException("Failed to initialize the application context", e);
  91.         }
  92.     }
  93.     /**
  94.      * 从缓存中获取 Bean 实例。
  95.      *
  96.      * @param beanName Bean 的名称
  97.      * @return Bean 实例
  98.      */
  99.     private Object getSingleton(String beanName) {
  100.         // 从一级缓存中获取
  101.         Object singleton = singletonObjects.get(beanName);
  102.         if (singleton == null) {
  103.             // 从二级缓存中获取
  104.             singleton = earlySingletonObjects.get(beanName);
  105.             if (singleton == null) {
  106.                 // 从三级缓存中获取 Bean 工厂并创建实例
  107.                 ObjectFactory<?> singletonFactory = singletonFactories.get(beanName);
  108.                 if (singletonFactory != null) {
  109.                     singleton = singletonFactory.getObject();
  110.                     // 将实例放入二级缓存
  111.                     earlySingletonObjects.put(beanName, singleton);
  112.                     singletonFactories.remove(beanName);
  113.                 }
  114.             }
  115.         }
  116.         return singleton;
  117.     }
  118.     @Override
  119.     public Object getBean(String name) {
  120.         return getSingleton(name);
  121.     }
  122.     @Override
  123.     @SuppressWarnings("unchecked")
  124.     public <T> T getBean(String name, Class<T> requiredType) {
  125.         Object bean = getBean(name);
  126.         if (requiredType.isInstance(bean)) {
  127.             return (T) bean;
  128.         }
  129.         throw new ClassCastException("Bean is not of required type: " + requiredType.getName());
  130.     }
  131.     /**
  132.      * 将字符串转换为指定的类型。
  133.      *
  134.      * @param typeName 属性类型的名称
  135.      * @param propertyValueStr 属性值的字符串表示
  136.      * @return 转换后的属性值
  137.      * @throws Exception 如果不支持该类型
  138.      */
  139.     public static Object changeType(String typeName, String propertyValueStr) throws Exception {
  140.         Object propertyValue = null;
  141.         switch (typeName) {
  142.             case "byte", "Byte":
  143.                 propertyValue = Byte.parseByte(propertyValueStr);
  144.                 break;
  145.             case "short", "Short":
  146.                 propertyValue = Short.parseShort(propertyValueStr);
  147.                 break;
  148.             case "int", "Integer":
  149.                 propertyValue = Integer.parseInt(propertyValueStr);
  150.                 break;
  151.             case "float", "Float":
  152.                 propertyValue = Float.parseFloat(propertyValueStr);
  153.                 break;
  154.             case "double", "Double":
  155.                 propertyValue = Double.parseDouble(propertyValueStr);
  156.                 break;
  157.             case "boolean", "Boolean":
  158.                 propertyValue = Boolean.parseBoolean(propertyValueStr);
  159.                 break;
  160.             case "long", "Long":
  161.                 propertyValue = Long.parseLong(propertyValueStr);
  162.                 break;
  163.             case "char", "Character":
  164.                 propertyValue = propertyValueStr.charAt(0);
  165.                 break;
  166.             case "String":
  167.                 propertyValue = propertyValueStr;
  168.                 break;
  169.             default:
  170.                 throw new Exception("不支持该类型");
  171.         }
  172.         return propertyValue;
  173.     }
  174.     /**
  175.      * ObjectFactory 接口用于创建 Bean 实例。
  176.      *
  177.      * @param <T> Bean 的类型
  178.      */
  179.     public interface ObjectFactory<T> {
  180.         T getObject();
  181.     }
  182. }
复制代码
代码分析


  • 构造函数:

    • 读取设置文件并剖析全部的Bean界说。
    • 将Bean工厂放入三级缓存(singletonFactories)。

  • 第一次遍历:

    • 创建Bean的工厂并将其放入三级缓存,以延长Bean的实例化。

  • 第二次遍历:

    • 从三级缓存中获取Bean实例,并将其放入二级缓存(earlySingletonObjects)。
    • 添补Bean的属性。如果属性是引用范例,从二级缓存中获取依赖Bean。

  • 完成初始化:

    • 将完全初始化的Bean从二级缓存移至一级缓存(singletonObjects)。

  • changeType方法:

    • 将属性值字符串转换为相应的范例(比方int、String等)。

  • ObjectFactory接口:

    • 用于界说创建Bean实例的方法。

通过上述代码和分析,你可以实现一个简朴的三级缓存机制,处理处罚Bean的创建和依赖注入。这种实现方式可以有效地管理Bean的生命周期,并办理循环依赖等复杂题目。渴望这篇博客能资助你明白和实现三级缓存机制。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表