低级容器BeanFactory可以理解为就是个HashMap,Key是BeanName,Value是Bean实例,通常只提供注册(put),获取(get)这两个功能;是IOC容器的基础接口,所有的容器都是从它这里继承实现而来,BeanFactory作为SpringIOC容器,管理着Bean的生命周期,控制着Bean的依赖注入;
它实现的核心功能就是根据名称或类型来返回一个bean实例,一个工厂如果要具备这种功能它需要具备以下几个条件:
以上两种信息都依赖于我们的配置信息定义,比如xml配置文件,工厂需要一个工具来读取配置文件的信息,配置方式可以有:在XML中进行显式配置;在Java中进行显式配置;注解方式;
类的依赖关系通过注入方式实现:Spring提供了三种注入方式:构造方法注入;setter方法注入;注解方式注入;类的依赖关系及bean的属性定义保存在BeanDefinition(加载所有的Bean配置成BeanDefinition到容器中,如果Bean有依赖关系,则使用占位符暂时代替);
调用BeanFactory.getBean的时候,从BeanDefinition所属的Map里,拿出Class对象进行实例化,同时如果有依赖关系,将递归调用(原因:因为加载的顺序不同,很可能Bean_A依赖的Bean_B还没有加载好,也就无法从容器中获取)getBean方法(即如果碰到了属性是ref的(占位符),那么就从容器里获取这个Bean)——完成依赖注入;
比BeanFactory多了更多的功能,定义了一个refresh方法,用于刷新整个容器,即重新加载/刷新所有的bean;
//AnnotatinonConfigApplicationContext:从一个或多个基于Java的配置类中加载Spring应用上下文;
ApplicationContext context = new AnnotatinonConfigApplicationContext(com.cmos.DemoConfig.class);
//AnnotationConfigWebApplicationContext:从一个或多个基于Java的配置类中加载SpringWeb应用上下文。
ApplicationContext context = new ClassPathXmlApplicationContext("demo.xml");
//ClassPathXmlApplicationContext:从类路径下的一个或多个XML配置文件中加载上下文定义,把应用上下文的定义文件作为类资源
//FileSystemXmlApplicationContext:从文件系统下的一个或多个XML配置文件中加载上下文定义;
ApplicationContext context = new FileSystemXmlApplicationContext("c:/demo.xml");
XmlWebApplicationContext:从Web应用下的一个或多个XML配置文件中加载上下文定义;
refresh()方法里列出了IOC容器初始化的步骤,第一个方法是初始化准备,这里只是设置启动日期和活动标识以及执行属性源的初始化,走到抽象方法refreshBeanFactory(),IOC容器开始初始化,第一步先判断有没有现有的工厂,有的话就销毁掉,然后创建一个默认的工厂,也就是DefaultListableBeanFactory ,接下来两行代码是设置bean工厂的一些属性,注意看loadBeanDefinitions(beanFactory)这行,当创建了一个默认的bean工厂后,加载bean定义,首先定义了一个Reader,这个Reader就是用来读取xml配置文件,spring将资源返回的输入流包装以后传给了doLoadBeanDefinitions()方法,spring将包装的输入流解析成DOM文档,然后将DOM中包含的bean定义信息注册到IOC容器持有的Map<String,BeanDefinition>对象中,只要IOC容器持有了bean定义,就能正确的生产bean实例;
注:代码省略