手写简单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

Java泛型

泛型定义 先看这样一个例子: public static void main(String[] args) { List list = new ArrayList(); list.add("aaa"); list.add("bbb"); list.add("ccc"); for (int i = 0; i < list.size(); i++) { System.out.println((String)list.get(i)); } } ArrayList集合中可以加入任何类型的对象,我本意是用这个集合来存储字符串(因为ArrayList默认存储的是Object类型的对象,所以输出时需要强转 ),但我粗心的写错了list.add(123),在我运行后发现报错java.lang.ClassCastException,显然报错原因就是输出时Integer类型并不能强转为String类型。那么如何避免这种情况呢,答案就是泛型。 借用一下维基百科的定义: 泛型程序设计是程序设计语言的一种风格或范型,泛型允许程序员在强类型程序设计语言中 编写代码时 使用一些 以后才指定的类型,在实例化时作为参数指明这些类型。 说一下我的理解,泛字让我联想到了一个词语:泛泛而谈,指那些浮浅平淡,不深入的谈话。这里也可以这样理解,定义时我模糊的说明一下参数,不指明参数具体是哪种类型,等我使用时再说明。 有这样一种说法:泛型的本质就是“参数化类型”。想象一下,定义一个方法需要形参,待你调用时,又需要传递实参。泛型亦是如此,定义时形式上意思意思,真正使用时再说明。其实都一个意思。 下面我将从泛型类、泛型方法、泛型接口、通配符、类型擦除五个方面来对Java泛型进行详细说明。 泛型类 来看一下ArrayList这个类的定义 public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {...} 相比其他普通类,这个类的类名称后面多了个<E>,这就是泛型类的核心标识,其中 E 为类型参数,理论上可以为任何字母,但有一些约定俗成的习惯 T:代表一般的任何类 E:element 元素的意思 K:代表 key 的意思 V:代表 value 的意思,经常和 K 搭配作为键值对 关于类型参数怎么用,来看个例子。 ...

October 14, 2025 · 4 分钟 · 741 字 · Me