手写简单IoC容器

学习 Spring,跟着二哥简单写个 IoC 容器。 @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface MyAutowired { } @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface MyComponent { } public class SimpleIoC { Map<Class<?>, Object> beans = new HashMap<>(); //扫描 public void scan(String packageName) { List<Class<?>> classes = getClassesInPackage(packageName); for (Class<?> clazz : classes) { if (clazz.isAnnotationPresent(MyComponent.class)) { registerBean(clazz); } } di(); } //获取包下的类,简化实现 private List<Class<?>> getClassesInPackage(String packageName) { // 实际实现需要扫描classpath,这里简化处理. return Arrays.asList(UserDao.class, UserService.class); } //注册bean private void registerBean (Class<?> clazz) { try { Object instance = clazz.getDeclaredConstructor().newInstance(); beans.put(clazz, instance); } catch (Exception e) { throw new RuntimeException("创建bean失败"); } } //获取bean @SuppressWarnings("unchecked") public <T> T getBean(Class<T> clazz) { return (T)beans.get(clazz); } //依赖注入 private void di() { for (Object bean : beans.values()) { Field[] fields = bean.getClass().getDeclaredFields(); for (Field field : fields) { if (field.isAnnotationPresent(MyAutowired.class)) { field.setAccessible(true); Object dependency = getBean(field.getType()); try { field.set(bean, dependency); } catch (Exception e) { throw new RuntimeException("依赖注入失败"); } } } } } } //DAO层 @MyComponent class UserDao { public void save(String user) { System.out.println("保存用户: " + user); } } // Service层 @MyComponent class UserService { @MyAutowired private UserDao userDao; public void createUser(String name) { userDao.save(name); System.out.println("用户创建完成"); } } class Test { public static void main(String[] args) { SimpleIoC ioc = new SimpleIoC(); ioc.scan("package"); UserService bean = ioc.getBean(UserService.class); bean.createUser("dong"); } } 参考链接: ...

March 7, 2026 · 1 分钟 · 210 字 · Me

MySQL锁机制八股整理

整理一下MySQL锁的八股,全文整理自二哥博客。 在MySQL数据库中,锁是用来协调多个进程或线程并发访问同一资源的机制。锁不仅保证了数据的一致性和有效性,而且是影响数据库并发访问性能的一个重要因素。 共享锁与排他锁 共享锁也叫 S(shared) 锁,允许多个事务进行读操作,阻塞写操作。 排他锁也叫 X(exclusive) 锁,只允许一个事务进行读写操作,阻塞其他事务的读写操作。 兼容性如下: 表锁与行锁 表锁:锁定整个表,资源开销小,加锁快,但并发度低,不会出现死锁,适合查询为主、少量更新的场景(如 MyISAM 引擎)。可以细分为表级S锁、表级X锁。 行锁:锁定单行或多行,开销大、加锁慢,可能出现死锁,但并发度高(InnoDB 默认支持)。可以细分为记录锁、间隙锁、临键锁,也可以分为共享锁和排他锁(与表级S锁、表级X锁一个意思,前提是行锁)。 表锁详细版: 表锁常见于 MyISAM 引擎, InnoDB 也可手动加锁,适合读多写少、全表扫描或者表结构变更的场景。 LOCK TABLES table_name READ; -- 显式加读锁 select... -- 其他会话可读,不可写 UNLOCK TABLES; -- 释放锁 LOCK TABLES table_name WRITE; -- 显式加写锁 INSERT/UPDATE/DELETE table_name; -- 其他会话读写均阻塞 UNLOCK TABLES; MyISAM 在执行 SELECT 时会自动加读锁,执行 INSERT/UPDATE/DELETE 时会加写锁。 对于 InnoDB 引擎,无索引的 UPDATE/DELETE 可能会导致锁升级为表锁。执行 ALTER TABLE 时会自动加表锁,阻塞所有读写操作。 行锁详细版: 行锁是 InnoDB 存储引擎中最细粒度的锁,它锁定表中的一行记录,允许其他事务访问表中的其他行。 底层是通过给索引加锁实现的,这就意味着只有通过索引条件检索数据时,InnoDB 才能使用行级锁,否则会退化为表锁。 ...

December 6, 2025 · 1 分钟 · 114 字 · Me

MySQL索引八股整理

整理一下MySQL索引的八股。 索引介绍 索引是数据库中用于加速查询的数据结构,通过对表中某列或多列的值进行排序,可以快速定位所要查找的数据。就像小时候在汉语字典里查字时,会先根据偏旁笔画数找到偏旁,然后根据剩余笔画找到目标字,这比在整个字典中一个一个查找是快很多的。 索引分类 索引有以下分类 索引详细介绍 主键索引: 主键索引用于唯一标识表中的每条记录,其值必须唯一且非空。每个表只允许有一个主键索引,一般为表中的自增id。 创建主键时,数据库会自动生成主键索引。若没有指定主键,MySQL的InnoDB存储引擎会优先选择一个非空的唯一索引作为主键,如果没有符合条件的索引,MySQL会自动生成一个隐藏的聚簇索引。 唯一索引: 主键索引 = 唯一索引 + 非空,每个表可以有多个唯一索引,同时唯一索引允许值为NULL,这是和主键索引不同的地方。唯一索引强制字段值的唯一性,插入或更新时会触发唯一检查,适用于业务唯一性约束的字段,比如邮箱。在建表定义唯一键时,会自动生成唯一索引。 键和索引的区别在于键是逻辑概念,而索引是物理实现,在磁盘中有着实际的存储。 普通索引: 普通索引仅用于加速查询,不会限制字段值的唯一性。 全文索引 全文索引是MySQL一种优化文本数据检索的特殊类型索引,适用于CHAR, VARCHAR, TEXT等字段。MySQL 5.7 及以上版本内置了 ngram 解析器,可处理中文、日文和韩文等分词。全文索引底层不再是 B+ 树索引。 建表时通过 FULLTEXT (title, body) 来定义。通过 MATCH(col1, col2) AGAINST('keyword') 进行检索,默认按照降序返回结果,支持布尔模式查询。 + 表示必须包含; - 表示排除; * 表示通配符; -- 使用布尔模式查询 SELECT * FROM articles WHERE MATCH(title, content) AGAINST('+MySQL -Oracle' IN BOOLEAN MODE); 这样查询性能比LIKE '%keyword%'高很多。对于复杂的中文场景可以用Elasticsearch等专业搜索引擎替代。 B+ 树索引: B+ 树是一种高度平衡的多路查找树,能有效降低磁盘的 IO 次数,并且支持有序遍历和范围查询。 ...

November 24, 2025 · 2 分钟 · 225 字 · Me