Spring从3.1开始就建议使用DefaultListableBeanFactory和XmlBeanDefinitionReader这两个类了, XmlBeanFactory是DefaultListableBeanFactory的子类。
第一种创建Bean工厂的方式,比较简洁
XmlBeanFactory factory = new XMLBeanFactory(new ClassPathResource("Bean.xml"))
Preson p =(Person) factory.getBean(Person.class);
第二种创建Bean工厂
ClassPathResource resource = new ClassPathResource("beans.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(resource);
Spring加载资源并装配对象的过程:
-
定义好Spring的配置文件
-
通过Resurce对象将Spring配置文件进行抽象,抽象成一个Resource对象
-
定义好Bean工厂(各种BeanFactory)
-
定义好XMLBeanDefinitionReader对象,并将工厂作为参数传递进去供后续回调使用
-
通过XMLBeanDefinitionReader对象读取之前抽象出的Resource对象(包含XML文件的解析过程)
-
本质上,XML文件的解析是由XmlBeanDefinitionReader对象交由BeanDefinitionParserDelegate委托来完成的,实质上这里使用到了委托模式。
-
IOC容器创建完成,用户可以通过容器获取到所需的对象信息
注意: 在DefaultBeanDefinitionDocumentReader类中的doRegisterBeanDefinitions方法使用了经典的模板方法设计模式,子类可以重写preProcessXml与postProcessXml方法,实现对xml配置文件的自定义扩展。
总结
- Spring的bean实际上是缓存在CurrentHashMap对象中
- 在创建Bean之前,首先需要将该bean的创建标识设定好,表示该bean已经或是即将被创建,为的是增强缓存的效率。
- 根据bean的scope属性来确定是singleton还是prototype等范围,然后创建相应的bean对象。
- 通过Java反射来创建bean的实例,在创建之前首先检查访问修饰符,如果不是public,则调用setAccessible来突破Java的语法限制,使得可以通过私有的构造方法来创建对象实例
- 接下来,寻找bean的属性值,完成属性的注入
- 将所创建出的singleton对象添加到缓存当中,供下次调用使用