陈公子的博客

IOC容器设计

IOC容器介绍

提供getBean接口,支持依赖注入
示例代码地址: https://github.com/ChenXun1989/ioc-framework

IOC容器主要模块

  • ApplicationContext,IOC容器上下文,持有对象Map
  • BeanFactory 每一个类型(class) 对应一BeanFactory,提供获取类实现的接口,属性注入接口
  • CompentScan 收集相关配置信息,主要分xml和注解扫描两种

    IOC容器启动过程

  • ApplicationContext 创建
    1
    2
    3
    ApplicationContext context=new ApplicationContext("com.chenxun.framework.example.entity");
    Student s=(Student) context.getBean("student");
    s.test();
  • CompentScan 收集相关配置信息,解析出被ioc容器托管的class集合
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    private final List<String > list=new ArrayList<>();
    public void scan(String packageName){
    String parent= System.getProperty("user.dir");
    parent=parent+"/src/main/java";
    System.out.println(parent);
    String child=packageName.replaceAll("\\.", "/");
    File f=new File(parent ,child);
    for(File c:f.listFiles()){
    if(c.getName().endsWith(".java")){
    list.add(packageName+"."+c.getName().substring(0,c.getName().lastIndexOf(".")));
    }
    }
    };
    public List<String > getList(){
    return list;
    }
  • 创建对应类的BeanFactory
  • BeanFactory通过反射创建默认class默认实例对象
  • 把创建完的对象放入ApplicationContext持有的对象Map
  • 遍历beanFactory的Map,调用setProperties接口来完成依赖注入
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    private void init() throws ClassNotFoundException{
    compentScan.scan(backPackage);
    for(String clasName:compentScan.getList()){
    Class cls=Class.forName(clasName);
    Compent c=(Compent) cls.getAnnotation(Compent.class);
    if(c!=null){
    String key=c.value();
    BeanFactory bf=new SimpleBeanFactory(cls);
    beanFactorys.put(cls, bf);
    map.put(key, bf.getBean());
    }
    }
    for(Entry<Class, BeanFactory> entry :beanFactorys.entrySet()){
    entry.getValue().setProperties(map);
    }
    }
    先创建对象,再做依赖注入
    容器里面是原生对象还是代理对象,取决于beanfatory返回的对象实例
陈勋 wechat
欢迎扫码加入知识星球