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

504. Java 反射 - 创建一个简单的依赖注入框架

文章目录

  • 504. Java 反射 - 创建一个简单的依赖注入框架
    • 1. 什么是依赖注入(DI)?
    • 2. 我们的目标
    • 3. 定义注解
    • 4. 编写依赖工厂(DI 容器)
    • 5. 编写业务类示例
    • 6. 测试依赖注入
      • 输出:
    • 7. 总结

504. Java 反射 - 创建一个简单的依赖注入框架

1. 什么是依赖注入(DI)?

依赖注入(Dependency Injection,简称DI)是一种设计模式,它的核心思想是:
👉不要自己手动创建对象,而是让“工厂/框架”来为你准备好依赖对象并注入到业务类中

这样做的好处:

  • 解耦:业务类不再依赖具体实现,只依赖抽象。
  • 易于测试:可以轻松替换依赖(比如替换成 Mock 实现)。
  • 生命周期管理:框架可以统一管理对象的创建、销毁、单例复用等。

很多企业级框架(如Spring、Jakarta EE、Guice)都是基于这种机制构建的。


2. 我们的目标

我们要写一个简化版的 DI 框架,支持两个功能:

  1. 单例模式 (Singleton):某些类只需要一个全局共享实例。
  2. 自动注入 (Injection):框架能自动扫描并填充需要的依赖字段。

3. 定义注解

我们先定义两个注解:

  • @Singleton:表示该类只能有一个实例。
  • @Inject:表示该字段需要由框架来注入依赖。
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public@interfaceSingleton{}@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public@interfaceInject{}

4. 编写依赖工厂(DI 容器)

DependencyFactory负责:

  1. 检查类上是否有@Singleton注解,如果有则复用同一个实例。
  2. 使用反射扫描字段,找到@Inject注解,并创建/注入依赖对象。
publicclassDependencyFactory{privatestaticfinalMap<Class<?>,Object>singletons=newHashMap<>();publicstatic<T>TgetInstance(Class<T>clazz){try{// ✅ 单例处理if(clazz.isAnnotationPresent(Singleton.class)){if(singletons.containsKey(clazz)){return(T)singletons.get(clazz);}}// ✅ 通过无参构造器创建对象Tinstance=clazz.getConstructor().newInstance();// ✅ 依赖注入for(Fieldfield:clazz.getDeclaredFields()){if(field.isAnnotationPresent(Inject.class)){field.setAccessible(true);Objectdependency=getInstance(field.getType());// 递归创建field.set(instance,dependency);}}// ✅ 保存单例if(clazz.isAnnotationPresent(Singleton.class)){singletons.put(clazz,instance);}returninstance;}catch(Exceptione){thrownewRuntimeException("Failed to create instance for "+clazz,e);}}}

5. 编写业务类示例

@SingletonpublicclassUserRepository{publicStringgetUser(){return"User[Tom]";}}publicclassUserService{@InjectprivateUserRepositoryrepository;publicvoidprocessUser(){System.out.println("Processing: "+repository.getUser());}}

6. 测试依赖注入

publicclassMain{publicstaticvoidmain(String[]args){UserServiceservice=DependencyFactory.getInstance(UserService.class);service.processUser();}}

输出:

Processing:User[Tom]

这里UserService并没有自己 newUserRepository,而是通过框架自动注入得到的实例。


7. 总结

  • 对比现实框架:Spring 的@Autowired、Jakarta EE 的@Inject就是类似机制。
  • DI 的好处:降低耦合、集中管理依赖、便于扩展。
  • 局限性:我们这里的框架比较简化,不支持作用域、懒加载、构造函数注入等高级特性。
http://www.cnnetsun.cn/news/4207366.html

相关文章:

  • 门窗五金哪个品牌质量好?2026年十大进口高端品牌权威盘点,从家装到工程全覆盖
  • Linux命令-yum(RPM 包管理工具)
  • 基于QML的Windows 11风格虚拟键盘:从编译部署到自定义开发全指南
  • 制造业客户一句“系统不好用”,数字化软件的售后工程师为什么从不急着猜答案?
  • STM32-AFIO 12
  • AI编程时代技术债治理:从美团31万行重构看人机协同防控体系
  • 3ds Max雪景制作实战:PolySnowV4程序化建模与动态特效全解析
  • 2026年UPS选购指南:150-550元价位如何为电脑、NAS构建电力防线
  • OpenClaw边缘部署实战:工业场景下大模型轻量化落地指南
  • Oracle RMAN备份脚本、RMAN还原恢复测试、RMAN常用语句
  • 从设计文档到技术交底书:工程师必备的专利转化实战指南
  • Spring AI 11 · 元数据过滤 FilterExpression
  • Spring Boot在线问诊系统设计:多语言、弱网与医疗协同的实战挑战
  • Godot 4 实战:从零构建像素风农场模拟游戏核心系统
  • LangChain Agent集成MCP协议:实现AI工具即插即用的标准化方案
  • 拼多多算法团队招聘:推荐、搜索与广告算法核心技术解析
  • MLLM引导语义校正:用大模型优化AI视频生成逻辑
  • 2026年采购智能鞋头后跟定型机,选哪家工厂性价比更高?
  • 山东高考志愿填报机构口碑与适用分析
  • 抖音批量下载工具实战:主页合集一键归档
  • C#图像高速存储落盘:提高图像从内存中落盘存储到硬盘速度的几个方法
  • 前端面试实战:技术深度与表达策略
  • AssetRipper完整教程:免费开源的Unity资产提取工具,5分钟从.assets文件里找回整个游戏
  • FlywayGuard:IDEA插件解决Flyway SQL冲突
  • 本地AI相册实战:基于ONNX与Tesseract的私有化图片管理方案
  • 2026之后,通用咨询公司难再做B2B全案
  • 吴恩达AI Agent技能开发教程:从工具调用到实战部署全解析
  • Substance 3D Designer 风格化木板材质制作全流程解析
  • RocketMQ事务消息原理与面试深度解析
  • AI智能体本地部署与实战:从环境搭建到API集成全流程