纯java原生ioc容器通过反射+自定义注解(@mycomponent/@myinject)+map容器实现,支持包扫描、单例注册、字段/构造器注入及循环依赖检测,不依赖spring或第三方库。

不依赖 Spring 的纯 Java 原生依赖注入框架,核心是用反射 + 注解 + 容器管理三要素手动实现 IoC 容器。它不引入任何第三方库,只靠 JDK 自带的 java.lang.reflect、java.util 和自定义注解就能完成 Bean 扫描、依赖解析与字段/构造器注入。
定义自己的注入注解
先创建两个关键注解,标记哪些类要被管理、哪些字段需要注入:
-
@MyComponent:贴在类上,表示该类是受管 Bean(类似
@Component) -
@MyInject:贴在字段上,表示此处需自动注入依赖(类似
@Autowired)
二者都需用 @Retention(RetentionPolicy.RUNTIME) 和 @Target 正确定义作用范围,否则运行时反射读不到。
手动扫描并注册 Bean
启动时指定一个包路径(如 "com.example.service"),用 ClassLoader.getResource() 获取其对应 classpath 路径,再遍历所有 .class 文件,用 Class.forName() 加载类,检查是否带有 @MyComponent 注解。若有,就用 clazz.getDeclaredConstructor().newInstance() 创建实例,并存入 Map<class>, Object></class> 缓存中——这就是最简版的单例容器。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
递归解析并注入依赖
对每个已注册的 Bean 实例,调用 clazz.getDeclaredFields() 获取所有字段,过滤出带 @MyInject 的字段。对每个字段:
- 设为可访问:
field.setAccessible(true) - 根据字段类型(
field.getType())从容器中查找匹配的 Bean 实例 - 若找不到,尝试递归创建(即先 new 出它的依赖,再注入进当前对象)
- 最后执行
field.set(instance, dependency)
注意处理循环依赖:可加一个正在创建中的 Set<class>></class> 集合做检测,发现重复则抛异常或返回代理占位符。
支持构造器注入(可选增强)
若想兼容构造器注入,需改用 getDeclaredConstructors() 找到参数最多、且所有参数类型都在容器中可查到的构造器,再逐个解析参数类型并注入。相比字段注入,它更安全(避免空指针)、更利于不可变对象设计,但实现略复杂,需额外处理参数顺序和重载构造器选择逻辑。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










