首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java IoC 容器原理手寫實現:工廠模式 + 配置文件 + 反射

     編輯:Java 相關知識

IoC 核心思想

控制反轉 (Inversion of Control)**:對象創建與依賴管理從應用代碼移交給容器。配合 **DI (Dependency Injection)** 實現依賴注入。

手寫迷你 IoC 容器

1. 統一接口 ApplicationContext


public interface ApplicationContext {
    Object getBean(String name);
    Object getBean(String name, String className);
}

2. 配置文件讀取器 PropertiesReader


public class PropertiesReader {
    private final String fileName;
    public PropertiesReader(String fileName) { this.fileName = fileName; }

    public Map<String, String> load() {
        Properties props = new Properties();
        try (InputStream is = getClass().getClassLoader().getResourceAsStream(fileName)) {
            props.load(is);
        } catch (IOException e) { throw new RuntimeException(e); }
        Map<String, String> map = new HashMap<>();
        for (String key : props.stringPropertyNames()) {
            map.put(key, props.getProperty(key));
        }
        return map;
    }
}

3. 基於類路徑的實現 ClassPathXmlApplicationContext


public class ClassPathXmlApplicationContext implements ApplicationContext {
    private final Map<String, String> beanMap;
    public ClassPathXmlApplicationContext(String configFile) {
        this.beanMap = new PropertiesReader(configFile).load();
    }

    @Override
    public Object getBean(String name) {
        String className = beanMap.get(name);
        if (className == null) throw new IllegalArgumentException("No bean: " + name);
        try {
            System.err.println("創建 Bean: " + name + " -> " + className);
            return Class.forName(className).getDeclaredConstructor().newInstance();
        } catch (ReflectiveOperationException e) {
            throw new RuntimeException("Bean 實例化失敗: " + name, e);
        }
    }
    @Override public Object getBean(String name, String className) { return null; }
}

4. 配置文件 applicationContext.properties


student=com.example.Student
service=com.example.UserService
dao=com.example.UserDao

5. 測試


public class IoCTest {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.properties");
        Student s = (Student) ctx.getBean("student");
        s.setSid("15301");
        s.setSname("張三");
        System.out.println(s.getSid() + " " + s.getSname());
    }
}

關鍵點總結

  • 配置文件映射 beanName → 全限定類名
  • 反射 Class.forName().newInstance() 實例化 (需無參構造)
  • 容器管理單例/原型作用域 (此處簡化為每次新建)
  • Spring 進階:BeanDefinition 元數據、BeanPostProcessor 擴展點、循環依賴檢測、AOP 代理創建

擴展方向

  • 支持構造器注入 / Setter 注入 / @Autowired 字段注入
  • XML / 注解 / Java Config 多種配置源
  • 生命周期回調 (InitializingBean, DisposableBean)
  • 三級緩存解決循環依賴
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved