本文目录导读:

我来教你实现一个简单的IoC容器,从基础到逐步完善,我会用Java语言演示,因为它的反射机制最清晰。
核心概念
IoC容器的三个核心功能:
- 注册:告诉容器哪些类需要管理
- 解析:分析类之间的依赖关系
- 注入:自动创建依赖实例
最简实现
先从一个基础版本开始:
import java.lang.reflect.Field;
import java.util.*;
// 注解:标记需要注入的字段
@interface Inject {
}
// 简单IoC容器
class SimpleContainer {
// 存储已注册的类和对应的实例
private Map<Class<?>, Object> instances = new HashMap<>();
// 注册接口与实现类
public <T> void register(Class<T> interfaceClass, T implementation) {
instances.put(interfaceClass, implementation);
}
// 获取bean实例(自动注入依赖)
@SuppressWarnings("unchecked")
public <T> T getBean(Class<T> clazz) throws Exception {
// 如果已有实例,直接返回
if (instances.containsKey(clazz)) {
return (T) instances.get(clazz);
}
// 创建新实例
T instance = clazz.getDeclaredConstructor().newInstance();
instances.put(clazz, instance);
// 注入依赖
injectDependencies(instance);
return instance;
}
// 注入依赖
private void injectDependencies(Object instance) throws Exception {
Class<?> clazz = instance.getClass();
// 遍历所有字段
for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(Inject.class)) {
field.setAccessible(true);
// 获取依赖的类型
Class<?> fieldType = field.getType();
// 递归获取依赖实例
Object dependency = getBean(fieldType);
field.set(instance, dependency);
}
}
}
}
使用示例
// 定义接口和类
interface Database {
void query(String sql);
}
class MySQLDatabase implements Database {
@Override
public void query(String sql) {
System.out.println("MySQL执行: " + sql);
}
}
class UserService {
@Inject // 标记需要注入
private Database database;
public void findUser(int id) {
database.query("SELECT * FROM users WHERE id = " + id);
}
}
// 使用容器
public class Main {
public static void main(String[] args) throws Exception {
SimpleContainer container = new SimpleContainer();
// 注册数据库实现
container.register(Database.class, new MySQLDatabase());
// 获取UserService(自动注入Database)
UserService userService = container.getBean(UserService.class);
userService.findUser(1);
}
}
增强版本
添加更多功能:
import java.lang.reflect.Constructor;
import java.util.*;
// 支持单例和原型模式
enum Scope {
SINGLETON, // 单例
PROTOTYPE // 原型(每次新建)
}
// 增强的容器
class AdvancedContainer {
// 存储单例实例
private Map<Class<?>, Object> singletons = new HashMap<>();
// 存储Bean定义
private Map<Class<?>, BeanDefinition> beanDefinitions = new HashMap<>();
// Bean定义
static class BeanDefinition {
Class<?> clazz;
Scope scope = Scope.SINGLETON;
BeanDefinition(Class<?> clazz) {
this.clazz = clazz;
}
}
// 注册类
public void register(Class<?> clazz) {
beanDefinitions.put(clazz, new BeanDefinition(clazz));
}
// 注册并指定作用域
public void register(Class<?> clazz, Scope scope) {
BeanDefinition def = new BeanDefinition(clazz);
def.scope = scope;
beanDefinitions.put(clazz, def);
}
// 获取Bean
@SuppressWarnings("unchecked")
public <T> T getBean(Class<T> clazz) throws Exception {
BeanDefinition def = beanDefinitions.get(clazz);
if (def == null) {
throw new IllegalArgumentException("Bean not registered: " + clazz);
}
// 单例模式
if (def.scope == Scope.SINGLETON) {
if (!singletons.containsKey(clazz)) {
singletons.put(clazz, createInstance(clazz));
}
return (T) singletons.get(clazz);
}
// 原型模式
return (T) createInstance(clazz);
}
// 创建实例并注入依赖
private Object createInstance(Class<?> clazz) throws Exception {
// 查找合适的构造器
Constructor<?> constructor = findConstructor(clazz);
Object instance;
if (constructor != null) {
// 通过构造器注入
Class<?>[] paramTypes = constructor.getParameterTypes();
Object[] params = new Object[paramTypes.length];
for (int i = 0; i < paramTypes.length; i++) {
params[i] = getBean(paramTypes[i]);
}
instance = constructor.newInstance(params);
} else {
// 使用默认构造器
instance = clazz.getDeclaredConstructor().newInstance();
}
// 字段注入
injectFields(instance);
return instance;
}
// 查找带@Inject注解的构造器
private Constructor<?> findConstructor(Class<?> clazz) {
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
if (constructor.isAnnotationPresent(Inject.class)) {
return constructor;
}
}
return null;
}
// 字段注入
private void injectFields(Object instance) throws Exception {
Class<?> clazz = instance.getClass();
for (java.lang.reflect.Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(Inject.class)) {
field.setAccessible(true);
Object dependency = getBean(field.getType());
field.set(instance, dependency);
}
}
}
}
完整的实战示例
// 演示基于接口的编程
interface Logger {
void log(String message);
}
class ConsoleLogger implements Logger {
@Override
public void log(String message) {
System.out.println("[Console] " + message);
}
}
// 使用构造器注入
class OrderService {
private final Logger logger;
private final Database database;
@Inject // 标记构造器注入
public OrderService(Logger logger, Database database) {
this.logger = logger;
this.database = database;
}
public void createOrder(String orderId) {
logger.log("Creating order: " + orderId);
database.query("INSERT INTO orders VALUES ('" + orderId + "')");
logger.log("Order created successfully");
}
}
// 测试
public class Demo {
public static void main(String[] args) throws Exception {
AdvancedContainer container = new AdvancedContainer();
// 注册组件
container.register(ConsoleLogger.class);
container.register(MySQLDatabase.class);
container.register(OrderService.class);
// 创建服务(依赖自动注入)
OrderService orderService = container.getBean(OrderService.class);
orderService.createOrder("ORD-001");
}
}
关键设计要点
- 类型识别:使用
Class<?>作为键来标识和管理Bean - 依赖解析:通过反射分析构造器参数和字段
- 生命周期管理:区分单例和原型模式
- 循环依赖处理:可以通过三级缓存解决(Spring的方案)
这个实现虽然简单,但包含了IoC容器的核心思想,实际生产中可以借鉴Spring的实现思路,添加更多功能如AOP、配置文件支持等。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播