https://www.cnblogs.com/VergiLyn/p/6130188.html
1:spring 直接读取xml配置文件方式有两种:
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanFactory.xml)); (3.1以后已被过时注解@Deprecated)
ApplicationContext ct = new ClassPathXmlApplicationContext("applicationContext.xml");
XmlBeanFactory分析
XmlBeanFactory继承了DefaultListableBeanFactory;而DefaultListableBeanFactory是整个spring bean 加载的核心,是spring注册和加载 bean的默认实现。而xmlBeanFactory继承后最大的改变就是自己内部实现了XmlBeanDefinitionReader的实例,完成对xml文件的个性化读取。DefaultListableBeanFactory整体继承关系结构图如下:
(1)BeanFactory 定义获取bean及bean的属性
(2)BeanDefinitionRegistry :定义对BeanDifinition的各种增删改操作,就是beandefinition的注册类;
(3)AutowireCapableBeanFactory:提供创建bean,自动主入,初始化以及应用bena的后处理器;
(4):ConfigurableBeanFactory:提供配置Factory的各种方法;
(5):ListableBeanFactory : 根据各种条件下获取bean的配置清单。
(6):ConfigureableListableBeanFactory:BeanFactory配置清单,指定忽略类型及接口等。
(7):DefaultListableBeanFactory:综上所用功能,主要是对bean的注册后的处理。
xml读取类:XmlBeanDefinitionReader将resource文件转化为Document文件,然后使用BeanDefinitionDocumentReader的DefaultBeanDefinitionDoucmentRrader类对Doucument进行解析,并使用BeanDefinitionParserDelegate对Element进行解析。
XmlBeanDefinitionReader方法loadBeanDefinitions读取资源文件,进入到doLoadBeanDefinitions方法,进行bean的提取解析;
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isInfoEnabled()) {
logger.info("Loading XML bean definitions from " + encodedResource.getResource());
}
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet<EncodedResource>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
finally {
inputStream.close();
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
Document doc = doLoadDocument(inputSource, resource);
return registerBeanDefinitions(doc, resource);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (SAXParseException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
}
catch (SAXException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"XML document from " + resource + " is invalid", ex);
}
catch (ParserConfigurationException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Parser configuration exception parsing XML from " + resource, ex);
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"IOException parsing XML document from " + resource, ex);
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Unexpected exception parsing XML document from " + resource, ex);
}
}
doLoadBeanDefinitions方法首先对xml文件格式,进行验证,两种验证模式,如DTD和XSD格式;并将传入进了的资源文件流转出document对象,进入registerBeandefinitions方法。
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
documentReader.setEnvironment(getEnvironment());
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
registerBeandefinitions方法引入BeanDefinitionDocumentReader类,进行doucment文档的root节点提取,读取,注册。进而跳转到doRegisterBeanDefinitions方法。
protected void doRegisterBeanDefinitions(Element root) {
// Any nested <beans> elements will cause recursion in this method. In
// order to propagate and preserve <beans> default-* attributes correctly,
// keep track of the current (parent) delegate, which may be null. Create
// the new (child) delegate with a reference to the parent for fallback purposes,
// then ultimately reset this.delegate back to its original (parent) reference.
// this behavior emulates a stack of delegates without actually necessitating one.
//xml bean标签元素解析器
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
//对web环境中,web.xml提取开发环境或者生产环境属性值
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
return;
}
}
}
preProcessXml(root);//模板方法,没有代码逻辑,用户可以自定义实现
//进入真正核心阶段
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);
this.delegate = parent;
}
其中parseBeanDefinitions方法,对元素标签进行提出,分别进行处理,注册。
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
//是否是默认标签,如bean,import,beans等
if (delegate.isDefaultNamespace(ele)) {
//默认标签解析
parseDefaultElement(ele, delegate);
}
else {
//自定义标签解析
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
其中BeanDefinitionParserDelegate中保存了所有默认标签的定义,如id,name,default-init-method,default-destroy-method等。