当前位置: 首页 > news >正文

如何编写自己的Spring容器

要编写自己的Spring容器,需实现核心功能:Bean定义、依赖注入、生命周期管理。以下是一个简化版的实现指南:

一、核心组件设计

1. BeanDefinition(Bean元数据)
public class BeanDefinition {private Class<?> beanClass;private String beanName;private Map<String, Object> properties = new HashMap<>();private String initMethodName;private String destroyMethodName;// Getters & Setters
}
2. Bean注册表(线程安全)
public class BeanRegistry {private final Map<String, BeanDefinition> beanDefinitions = new ConcurrentHashMap<>();private final Map<String, Object> singletonBeans = new ConcurrentHashMap<>();public void registerBeanDefinition(String beanName, BeanDefinition bd) {beanDefinitions.put(beanName, bd);}public BeanDefinition getBeanDefinition(String beanName) {return beanDefinitions.get(beanName);}
}
3. 容器核心接口
public interface BeanFactory {Object getBean(String name) throws Exception;
}

二、容器启动流程

1. 配置加载(示例:注解扫描)
public class AnnotationConfigApplicationContext extends BeanRegistry implements BeanFactory {public AnnotationConfigApplicationContext(Class<?> configClass) {scanComponents(configClass.getPackage().getName());refresh();}private void scanComponents(String packageName) {// 使用反射扫描指定包下的@Component注解类// 示例代码(需完善包扫描逻辑):Set<Class<?>> classes = ClassPathScanning.getClasses(packageName);for (Class<?> clazz : classes) {if (clazz.isAnnotationPresent(Component.class)) {Component component = clazz.getAnnotation(Component.class);String beanName = component.value().isEmpty() ? clazz.getSimpleName().toLowerCase() : component.value();registerBeanDefinition(beanName, createBeanDefinition(clazz));}}}
}
2. BeanDefinition解析
private BeanDefinition createBeanDefinition(Class<?> clazz) {BeanDefinition bd = new BeanDefinition();bd.setBeanClass(clazz);bd.setBeanName(clazz.getSimpleName().toLowerCase());// 解析字段上的@Autowired注解for (Field field : clazz.getDeclaredFields()) {if (field.isAnnotationPresent(Autowired.class)) {bd.getProperties().put(field.getName(), field.getType().getName());}}return bd;
}
3. 实例化与依赖注入
public Object getBean(String name) throws Exception {if (singletonBeans.containsKey(name)) {return singletonBeans.get(name);}BeanDefinition bd = getBeanDefinition(name);Object instance = bd.getBeanClass().newInstance();// 依赖注入for (Field field : bd.getBeanClass().getDeclaredFields()) {if (bd.getProperties().containsKey(field.getName())) {String dependencyName = bd.getProperties().get(field.getName());Object dependency = getBean(dependencyName);field.setAccessible(true);field.set(instance, dependency);}}// 初始化回调if (bd.getInitMethodName() != null) {Method initMethod = bd.getBeanClass().getMethod(bd.getInitMethodName());initMethod.invoke(instance);}singletonBeans.put(name, instance);return instance;
}

三、生命周期管理

1. Aware接口回调
// 在getBean中添加以下逻辑
if (instance instanceof BeanNameAware) {((BeanNameAware) instance).setBeanName(name);
}
if (instance instanceof BeanFactoryAware) {((BeanFactoryAware) instance).setBeanFactory(this);
}
2. 初始化阶段
// 在getBean中调用BeanPostProcessor(需实现扩展点)
for (BeanPostProcessor processor : beanPostProcessors) {instance = processor.postProcessBeforeInitialization(instance, name);
}// 执行初始化方法
if (bd.getInitMethodName() != null) {Method initMethod = bd.getBeanClass().getMethod(bd.getInitMethodName());initMethod.invoke(instance);
}for (BeanPostProcessor processor : beanPostProcessors) {instance = processor.postProcessAfterInitialization(instance, name);
}
3. 销毁阶段
public void close() {for (String beanName : singletonBeans.keySet()) {BeanDefinition bd = getBeanDefinition(beanName);Object bean = singletonBeans.get(beanName);if (bean instanceof DisposableBean) {((DisposableBean) bean).destroy();}if (bd.getDestroyMethodName() != null) {Method destroyMethod = bd.getBeanClass().getMethod(bd.getDestroyMethodName());destroyMethod.invoke(bean);}}
}

四、依赖注入实现

1. 反射工具类
public class ReflectionUtils {public static void setField(Object target, String fieldName, Object value) {Field field = target.getClass().getDeclaredField(fieldName);field.setAccessible(true);try {field.set(target, value);} catch (Exception e) {throw new RuntimeException("Failed to set field: " + fieldName, e);}}
}
2. 注解定义
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {String value() default "";
}@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {}

五、使用示例

1. 定义Bean
@Component
public class UserService {@Autowiredprivate UserRepository userRepository;public void init() {System.out.println("UserService initialized");}
}@Component
public class UserRepository {// ...
}
2. 启动容器
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = (UserService) context.getBean("userService");

六、扩展功能

  1. BeanPostProcessor:实现自定义Bean增强逻辑
  2. 作用域支持:在BeanDefinition中添加scope字段,实现原型模式
  3. 配置文件支持:解析XML或Properties文件生成BeanDefinition
  4. 事件发布:实现ApplicationEventPublisher接口

通过以上步骤,你可以构建一个基础版的Spring容器,涵盖核心的IoC和DI功能。实际生产环境中的Spring容器更为复杂,但此示例展示了其核心设计思想。

http://www.lryc.cn/news/624899.html

相关文章:

  • 【EI会议征稿】2025第四届健康大数据与智能医疗国际会议(ICHIH 2025)
  • VS Code Copilot 完整使用教程(含图解)
  • 全局锁应用场景理解
  • 深度学习——R-CNN及其变体
  • 04 类型别名type + 检测数据类型(typeof+instanceof) + 空安全+剩余和展开(运算符 ...)简单类型和复杂类型 + 模块化
  • Spark 运行流程核心组件(三)任务执行
  • 实习两个月总结
  • [系统架构设计师]软件架构的演化与维护(十)
  • SpringBoot--JWT
  • 大数据计算引擎(四)—— Impala
  • React diff——差异协调算法简介
  • 深入解析 Qwen3 GSPO:一种稳定高效的大语言模型强化学习算法
  • 整体设计 之“凝聚式中心点”原型 --整除:智能合约和DBMS的深层融合 之2
  • LLM - MCP传输协议解读:从SSE的单向奔赴到Streamable HTTP的双向融合
  • 【软考架构】第4章 信息安全的抗攻击技术
  • 群晖nas中 打开PHP连接MariaDB 功能扩展
  • CMakeLists.txt 学习笔记
  • SQL详细语法教程(六)存储+索引
  • Vue3+Vite MPA多页面应用开发完整指南 – 从零搭建到部署优化
  • 博客项目 Spring + Redis + Mysql
  • Linx--MySQL--安装笔记详细步骤!
  • B4265 [朝阳区小学组 2019] rectangle
  • SpringAI集成MCP
  • CentOS 7更换国内镜像源
  • SQL Server 基本语法
  • 传统方式部署(RuoYi-Cloud)微服务
  • 云原生:重塑软件世界的技术浪潮与编程语言选择
  • 使用websockets中的一些问题和解决方法
  • 华曦达港股IPO观察丨以创新研发为笔,构建AI Home智慧生活新蓝图
  • 8月更新!Windows 10 22H2 64位 五合一版【原版+优化版、版本号:19045.6159】