测试:
bean:
<bean id="myTestBean" class="com.it.bean.MyTestBean"></bean>
代码:
@Test
public void testSimpleLoad() {
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
MyTestBean testBean = (MyTestBean)factory.getBean("myTestBean");
System.out.println(testBean);
}
功能步骤分析:
(1)读取配置文件。
(2)通过配置文件中的类配置,找到该类进行实例化。
(3)调用实例化后的实例2
1、DefaultListableBeanFacoty
先简单的了解一下类图中的各个类的作用:
-
AliasRegistry :定义对alias的简单的增删改等操作。
-
SimpleAliasRegistry:主要使用map作为alias的缓存,对AliasRegistry进行实现。
-
SingletonBeanRegistry:定义对单例的注册和获取。
-
BeanFactory:定义获取bean及bean的各种属性。
-
DefaultSingletonBeanRegistry:对接口SingletonBeanRegistry各函数的实现。
-
HierarchicalBeanFactory:继承BeanFactory,在BeanFactory定义的功能的基础上增加对parentFactory的支持。
-
BeanDefinitionRegistry:定义对BeanDefinition的各种增删改操作。
-
FactoryBeanRegistrySupport:在DefaultSingletonBeanRegistry基础上增加了对FactoryBean的特殊处理功能。
-
ConfigurableBeanFactory:提供配置Facotry的各种方法。
-
ListableBeanFactory:根据各种条件获取bean的配置清单。
-
AbstractBeanFactory:综合FactoryBeanRegistrySupport和ConfigurableBeanFactory的功能。
-
AutowireCapableBeanFactory:提供创建bean、自动注入、初始化以及应用bean的后处理器。
-
AbstractAutowireCapableBeanFactory:综合AbstractBeanFactory并对接口AutowireCapableBeanFactory进行实现。
-
ConfigurableListableBeanFactory: BeanFactory配置清单,指定忽略类型和接口等。
-
DefaultListableBeanFactory:综合上面所有的功能,主要是对bean注册后的处理。
XmlBeanFactory对DefaultListableBeanFactory类进行了扩展,主要用于从XML文档中读取BeanDefinition,对于注册和获取Bean都是从父类DefaultListableBeanFactory继承实现的方法,而唯独与父类不同的个性化实现就是增加了XmlBeanDefinitionReader类型的reader属性。在xmlBeanFacotry中主要使用reader属性对资源文件进行读取和注册。
2、XmlBeanDefinitionReader
- ResourceLoader:定义资源加载器,主要用于给定的资源文件地址返回对应的Resource.
- BeanDefinitionReader:主要定义资源文件读取并转换卫BeanDefinition的各个功能。
- EnvironmentCapable:定义获取Environment方法。
- DocumentLoader:定义从资源文件加在到转换为Document的功能。
- AbstractBeanDefinitionReader:对BeanDefinitionReader、EnvironmentCapable类定义的功能进行实现。
- BeanDefinitionDocumentReader:定义读取Document和注册BeanDefinition功能。
- BeanDefinitionParserDelegate:定义解析Element的各种方法。
在XmlBeanDefinitionReader主要包含以下步骤的处理:
1、通过继承AbstractBeanDefinitionReader中的方法,来使用ResourceLoader将资源文件路径转换为对应的Resource文件。
2、通过DocumentLoader对Resource文件进行转换,将Resource文件转换为Document文件。
3、通过实现接口BeanDefinitionDocumentReader的DefaultBeanDefinitionDocumentReader类对Document进行解析,并使用BeanDefinitionParserDelegate对Elemnet进行解析。
1、加载Bean
1.1.1、测试:
1.1.2、通过***XmlBeanFactory***中的构造方法,进入到***XmlBeanDefinitionReader***中的***loadBeanDefinitions()***方法
1.1.3、对resource进行编码处理,主要作用是在EncodedResource中的***getReader()***,reader会设置指定的编码
1.1.4、通过resource获得一个InputStream并将其封装为InputSource,进行下一步操作
第一阶段总结:
考虑到传入的Resource可能存在编码要求,对Resource进行封装,其次通过SAX读取的方式来准备InputSource对象,最终传入到核心处理部分,我们的doLoadBeanDefinitions()
1.1.5、***doLoadBeanDefinitions()***做了两件事:封装文档Document、注册Bean
1.1.6 、***doLoadBeanDefinitions()***中的 ***doLoadDocument()***做了两件事:加载文档到Document、xml验证
1.1.7 没有手动指定xml验证模式,走自动xml验证***detectValidationMode()***(自动xml)
***detectValidationMode()*方法通过resource得到InputStream后通过构造转换流以及构造缓冲流,使用缓冲流特有方法readline()读取一行查找是否有一行含有DOCTYPE,如果含有DOCTYPE就是DTD模式、不含就是XSD模式。这一步是通过委托给XmlValidationModeDetector类去进行的。
1.1.8、回到1.1.6验证完后就开始加载文档,和通常SAX读取文档一样。
)]
1.1.9、回到1.1.5封装好了Document后,开始解析和注册Bean;这个方法中很好地应用了面向对象中单一职责的原则,将逻辑处理委托给单一的类进行处理,这个逻辑处理类就是***BeanDefinitionDocumentReader***,实际上***createBeanDefinitionDocumentReade()***通过反射实例化的是***DefaultBeanDefinitionDocumentReader***对象,***BeanDefinitionDocumentReader***是一个接口。
1.1.10、加载和注册Bean ***doRegisterBeanDefinitions()***,首先判断root元素中是否有profile属性,用来指定读取的配置,配置文件可以写两套配置,一套生产一套开发,便于切换环境。
1.1.11 parseBeanDefinitions(),spring的配置文件中存在两大类Bean声明,一种是默认的:
<bean id="test" class="test.TestBean"></bean> <!--使用ParseDefaultElement方法解析-->
另一种是自定义的:
<tx:annotation-driven/> <!--使用parseCustomElement方法解析-->
如何判断是否是默认的配置呢?通过这个Element中通过***getNameSpaceURI()***方法得到的和spring默认的“http://www.springframework.org/schema/beans”进行比较得出。
第二阶段总结:
判断了文档的约束类型,将文档封装成Document,开始解析配置文件,获取根元素