Spring -- 源码分析 -- XmlBeanFactory(。。。未完待续)
2019-06-18 14:50
274 查看
1、读取 xml,生成 dom 树
1、继承 DefaultListableBeanFactory,该类是 BeanFactory 容器的最终载体;使用 XmlBeanDefinitionReader 来加载xml
[code]//XmlBeanFactory.java 77行 public class XmlBeanFactory extends DefaultListableBeanFactory { this.reader.loadBeanDefinitions(resource); }
2、将 resource 资源,封装成 sax 需要的类型 InputSource
[code]//XmlBeanDefinitionReader.java 332行 InputSource inputSource = new InputSource(inputStream); return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
3、使用 sax 将资源转换为一棵 dom 树
[code]//XmlBeanDefinitionReader.java 391行 Document doc = doLoadDocument(inputSource, resource);
4、dom 解析原理
[code]//1.构造工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //2.注入命名空间,也就是在节点对象中显示命名空间 factory.setNamespaceAware(true); //3.开启验证 factory.setValidating(true); DocumentBuilder builder = factory.newDocumentBuilder(); //4.验证文件 xsd 和 dtd 的路径解析器 builder.setEntityResolver(new ResourceEntityResolver(new DefaultResourceLoader())); builder.setErrorHandler(null); //5.转化为 sax 需要的资源类型 InputSource source = new InputSource(new ClassPathResource("application-test.xml").getInputStream()); Document document = builder.parse(source); Element root = document.getDocumentElement(); System.out.println(root.getNamespaceURI()); NodeList list = root.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); if (node instanceof Element) { Element element = (Element) node; System.out.println(element.getAttribute("class")); System.out.println(element.getNamespaceURI()); } }
2、根据 dom 树节点解析 bean
1、使用 DefaultBeanDefinitionDocumentReader 来解析 dom 树
[code]//XmlBeanDefinitionReader.java 508行 documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); //DefaultBeanDefinitionDocumentReader 93行 Element root = doc.getDocumentElement(); doRegisterBeanDefinitions(root);
2、DefaultBeanDefinitionDocumentReader 委托 BeanDefinitionParserDelegate 解析节点
[code]//DefaultBeanDefinitionDocumentReader.java 145行 BeanDefinitionParserDelegate parent = this.delegate; this.delegate = createDelegate(this.readerContext, root, parent); //子类扩展1 preProcessXml(root); //解析 parseBeanDefinitions(root, this.delegate); //子类扩展2 postProcessXml(root);
3、根据命名空间使用默认或自定义解析
[code]//DefaultBeanDefinitionDocumentReader.java 168行 if (delegate.isDefaultNamespace(ele)) { parseDefaultElement(ele, delegate); }else { delegate.parseCustomElement(ele); }
4、解析默认命名空间标签,import、alias、bean、beans 标签
[code]//DefaultBeanDefinitionDocumentReader.java 182行 private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); } else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // recurse doRegisterBeanDefinitions(ele); } }
5、解析 bean 标签,注册到容器中
[code]//DefaultBeanDefinitionDocumentReader.java 305行 //1.开始解析标签 BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); //2.如果存在非默认标签, 继续解析 bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); //3.注册bean BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
6、解析准备
[code]//BeanDefinitionParserDelegate.java 437行 String id = ele.getAttribute(ID_ATTRIBUTE); String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); //...省略, 这部分是在解析别名 //真正的解析过程 AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); //...省略, 这部分是在为 bean 寻找名称 //返回 BeanDefinitionHolder 对象 String[] aliasesArray = StringUtils.toStringArray(aliases); return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
7、解析过程
[code]//BeanDefinitionParserDelegate.java 537行 AbstractBeanDefinition bd = createBeanDefinition(className, parent); //1.解析标签上属性, 如scope、abstract、lazy-init、depends-on、primary、init-method、destroy-method、factory-method、factory-bean parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); //2.解析 meta 元数据, 并不作为 bean 的属性存在, 但是可以从 bean 中获取 parseMetaElements(ele, bd); //3.标记覆盖方法 parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); //4.解析 constructor-arg 构造器属性 parseConstructorArgElements(ele, bd); //5.解析 property 内部标签 parsePropertyElements(ele, bd); //6.解析 qualifier 内部标签 parseQualifierElements(ele, bd)
3、注册 Bean
1、注册 bean,并注册别名
[code]//DefaultBeanDefinitionDocumentReader.java 311行 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); //BeanDefinitionReaderUtils.java 142行 public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { //1.注册bean String beanName = definitionHolder.getBeanName(); registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); //2.注册别名 String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String aliase : aliases) { registry.registerAlias(beanName, aliase); } } }
4、获取 Bean 过程
1、根据名称获取实例 bean
[code]ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application-test.xml"); BeanTest bean = (BeanTest) context.getBean("beanTest");
2、最终调用的是 AbstractBeanFactory 的 doGetBean 方法
[code]//AbstractBeanFactory.java 231行 //1.获取真正的 beanName, 主要是针对别名 final String beanName = transformedBeanName(name); //2.获取缓存的实例 bean Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { //3.实例化的 bean 不一定是最终需要的, 可能是工厂类, 这里需要使用工厂策略进行判断 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); }else { //4.当前BeanFactory没有该bean, 去父类BeanFactory查找 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { return (T) parentBeanFactory.getBean(nameToLookup, args); } final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); //5.实例化依赖 String[] dependsOn = mbd.getDependsOn(); for(;;;){ registerDependentBean(dependsOnBean, beanName); getBean(dependsOnBean); } if (mbd.isSingleton()) { //6.真正实例化bean的地方,使用的是工厂策略方法 sharedInstance = getSingleton(beanName, new ObjectFactory<>(){...}); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //7.实例化出来的 bean 不一定是想要的类型, 使用转换器进行转换 if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { return getTypeConverter().convertIfNecessary(bean, requiredType); } return (T) bean; }
2、获取缓存bean,该方法中出现了很多集合,理解起来有些困难,基本上是为了解决循环依赖而出现的
[code]//DefaultSingletonBeanRegistry.java 183行 Object singletonObject = this.singletonObjects.get(beanName); //...省略
3、实例化过程
[code]//AbstractAutowireCapableBeanFactory.java 445行 //1.根据类名,调用无参构造器进行初始化 resolveBeanClass(mbd, beanName); //2.标记覆盖方法 mbd.prepareMethodOverrides(); //3.在 bean 初始化之前,调用 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation,这里可以控制 bean 的生成,如果这里返回的 bean 不为null,那么后续的初始化不会调用,直接调用 postProcessAfterInitialization Object bean = resolveBeforeInstantiation(beanName, mbd); //4.真正实例化bean Object beanInstance = doCreateBean(beanName, mbd, args);
4、doCreateBean 方法(最复杂)
[code]//AbstractAutowireCapableBeanFactory.java 504行 BeanWrapper instanceWrapper = null;
。。。未完待续
相关文章推荐
- Spring源码分析之XmlbeanFactory继承关系图
- Spring源码分析:1.容器的基础XmlBeanFactory
- Spring源码深度解析第二章---核心类的介绍和XmlBeanFactory的源码分析
- 【Spring源码分析】原型Bean实例化过程、byName与byType及FactoryBean获取Bean源码实现
- 分析spring源码第一篇:DefaultListableBeanFactory
- Spring源码学习-5.ProxyFactoryBean实现与源代码分析
- Spring源码分析 为什么xml定义的bean优先于注解定义的bean ?
- Spring源码分析之ProxyFactoryBean方式实现Aop功能的分析
- Spring源代码分析(7)---XmlBeanFactory(迟来的正主)
- 浅析Spring AOP源码(十四) 分析ProxyFactoryBean
- Spring源码分析-BeanFactory
- spring 源码分析--第二章 AbstractBeanFactory
- 解析Spring源码(2)---new XmlBeanFactory(new ClassPathResource("..."))
- Spring源码分析之BeanPostProcessor接口和BeanFactoryPostProcessor接口方法不执行原因分析
- 分析Spring IoC源码(二)BeanFactory初始化
- Spring源码分析——BeanFactory体系之接口详细分析
- Spring源码分析之BeanFactory对象创建
- Spring源码学习之XmlBeanFactory的实现
- 2、Spring的LocalSessionFactoryBean创建过程源码分析
- spring beans源码解读之--XmlBeanFactory