当前位置: 首页 > news >正文

网络客服在家上班招聘嘉兴关键词优化报价

网络客服在家上班招聘,嘉兴关键词优化报价,凡科网微信小程序制作,南京房地产网站建设前面几章的内容已经介绍了BeanFactory创建前的准备工作,以及加载XML配置文件前的准备的步骤。本章会着重介绍解析XML的步骤。 registerBeanDefinitions 前几个方法不做过多的赘述,着重看registerBeanDefinitions方法中解析XML的步骤。 public int regi…

前面几章的内容已经介绍了BeanFactory创建前的准备工作,以及加载XML配置文件前的准备的步骤。本章会着重介绍解析XML的步骤。

registerBeanDefinitions

前几个方法不做过多的赘述,着重看registerBeanDefinitions方法中解析XML的步骤。

	public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {// 对xml的beanDefinition进行解析BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();int countBefore = getRegistry().getBeanDefinitionCount();// 完成具体的解析过程documentReader.registerBeanDefinitions(doc, createReaderContext(resource));return getRegistry().getBeanDefinitionCount() - countBefore;}

doRegisterBeanDefinitions

之前已经将XML转换成了Document对象,所以Element 元素就是XML配置文件中的最外层标签< beans >,并且看beans标签中是否配置了default-lazy-init,default-merge等属性,如果配置了则进行赋值。其中defaultNamespace就是XML配置文件中beans标签的xmlns属性中所对应的。主要是用来在网上对应地址进行校验XML。
在这里插入图片描述

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.BeanDefinitionParserDelegate parent = this.delegate;//创建Delegate,并且看beans标签中是否配置了default-lazy-init,default-merge等属性,设置默认值this.delegate = createDelegate(getReaderContext(), root, parent);//defaultNamespace = http://www.springframework.org/schema/beansif (this.delegate.isDefaultNamespace(root)) {String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);if (StringUtils.hasText(profileSpec)) {String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);// We cannot use Profiles.of(...) since profile expressions are not supported// in XML config. See SPR-12458 for details.if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {return;}}}preProcessXml(root);parseBeanDefinitions(root, this.delegate);postProcessXml(root);this.delegate = parent;}

parseBeanDefinitions
解析XML的具体操作,从beans标签节点开始逐层像里面遍历

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {if (delegate.isDefaultNamespace(root)) {//获取childNodeNodeList nl = root.getChildNodes();for (int i = 0; i < nl.getLength(); i++) {Node node = nl.item(i);if (node instanceof Element) {Element ele = (Element) node;if (delegate.isDefaultNamespace(ele)) {parseDefaultElement(ele, delegate);}else {delegate.parseCustomElement(ele);}}}}else {delegate.parseCustomElement(root);}}

parseDefaultElement

默认namespace,则走parseDefaultElement方法进行解析,只有Spring默认的标签,才会执行这个解析方式,默认标签共有import、alias、bean和beans四种。

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)) {// recursedoRegisterBeanDefinitions(ele);}}

processBeanDefinition

每种对应的解析方式也不同,以bean标签为例。创建一个BeanDefinitionHolder 对象用来封装

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {// beanDefinitionHolder是beanDefinition对象的封装类,封装了BeanDefinition,bean的名字和别名,用它来完成向IOC容器的注册// 得到这个beanDefinitionHolder就意味着beandefinition是通过BeanDefinitionParserDelegate对xml元素的信息按照spring的bean规则进行// 解析得到的BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);if (bdHolder != null) {bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);try {// Register the final decorated instance.// 向ioc容器注册解析得到的beandefinition的地方BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());}catch (BeanDefinitionStoreException ex) {}// Send registration event.// 在beandefinition向ioc容器注册完成之后,发送消息getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));}}

解析bean标签

获取bean标签中id属性和name属性,并检查唯一性,调用parseBeanDefinitionElement进一步解析bean下其他节点属性。
parseBeanDefinitionElement

	@Nullablepublic BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {// 解析id属性String id = ele.getAttribute(ID_ATTRIBUTE);// 解析name属性String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);// 如果bean有别名的话,那么将别名分割解析List<String> aliases = new ArrayList<>();if (StringUtils.hasLength(nameAttr)) {String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);aliases.addAll(Arrays.asList(nameArr));}String beanName = id;if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {beanName = aliases.remove(0);}if (containingBean == null) {checkNameUniqueness(beanName, aliases, ele);}// 对bean元素的详细解析AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);if (beanDefinition != null) {if (!StringUtils.hasText(beanName)) {try {// 如果不存在beanname,那么根据spring中提供的命名规则为当前bean生成对应的beanNameif (containingBean != null) {beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);}else {beanName = this.readerContext.generateBeanName(beanDefinition);// Register an alias for the plain bean class name, if still possible,// if the generator returned the class name plus a suffix.// This is expected for Spring 1.2/2.0 backwards compatibility.String beanClassName = beanDefinition.getBeanClassName();if (beanClassName != null &&beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {aliases.add(beanClassName);}}}catch (Exception ex) {error(ex.getMessage(), ele);return null;}}String[] aliasesArray = StringUtils.toStringArray(aliases);return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);}return null;}

parseBeanDefinitionElement
createBeanDefinition中创建的是GenericBeanDefinition,将解析好的属性值放到GenericBeanDefinition中,并封装到BeanDefinitionHolder中。

public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean) {this.parseState.push(new BeanEntry(beanName));// 解析class属性String className = null;if (ele.hasAttribute(CLASS_ATTRIBUTE)) {className = ele.getAttribute(CLASS_ATTRIBUTE).trim();}// 解析parent属性String parent = null;if (ele.hasAttribute(PARENT_ATTRIBUTE)) {parent = ele.getAttribute(PARENT_ATTRIBUTE);}try {// 创建装在bean信息的AbstractBeanDefinition对象,实际的实现是GenericBeanDefinitionAbstractBeanDefinition bd = createBeanDefinition(className, parent);// 解析bean标签的各种其他属性parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);// 设置description信息bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));// 解析元数据parseMetaElements(ele, bd);// 解析lookup-method属性parseLookupOverrideSubElements(ele, bd.getMethodOverrides());// 解析replaced-method属性parseReplacedMethodSubElements(ele, bd.getMethodOverrides());// 解析构造函数参数parseConstructorArgElements(ele, bd);// 解析property子元素parsePropertyElements(ele, bd);// 解析qualifier子元素parseQualifierElements(ele, bd);bd.setResource(this.readerContext.getResource());bd.setSource(extractSource(ele));return bd;} finally {this.parseState.pop();}return null;}

此时,整个bean标签已经全部加载完成,并封装到了一个BeanDefinitionHolder中,接下来,再回到BeanDefinitionHolder的操作。看解析完之后做了些什么。parseBeanDefinitionElement方法已经执行完,接下来是registerBeanDefinition。

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {// beanDefinitionHolder是beanDefinition对象的封装类,封装了BeanDefinition,bean的名字和别名,用它来完成向IOC容器的注册// 得到这个beanDefinitionHolder就意味着beandefinition是通过BeanDefinitionParserDelegate对xml元素的信息按照spring的bean规则进行// 解析得到的BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);if (bdHolder != null) {bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);try {// Register the final decorated instance.// 向ioc容器注册解析得到的beandefinition的地方BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());}catch (BeanDefinitionStoreException ex) {getReaderContext().error("Failed to register bean definition with name '" +bdHolder.getBeanName() + "'", ele, ex);}// Send registration event.// 在beandefinition向ioc容器注册完成之后,发送消息getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));}}

registerBeanDefinition
这个方法主要流程是获取封装进eanDefinitionHolder的beanName,注册到BeanFactory容器中。

public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)throws BeanDefinitionStoreException {// Register bean definition under primary name.// 使用beanName做唯一标识注册String beanName = definitionHolder.getBeanName();registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());// Register aliases for bean name, if any.// 注册所有的别名String[] aliases = definitionHolder.getAliases();if (aliases != null) {for (String alias : aliases) {registry.registerAlias(beanName, alias);}}}

registerBeanDefinition
beanDefinitionMap:ConcurrentHashMap<String, BeanDefinition> beanDefinitionMap类型(key:beanName,value:BeanDefinition)。
beanDefinitionNames:ArrayList< String > beanDefinitionNames类型。
如果beanDefinitionMap中key存在,证明加载解析过,则看allowBeanDefinitionOverriding是否允许类被覆盖(创建BeanFactory是设置的值),可以则覆盖,不可以则抛异常。
如果没加载过,则放到beanDefinitionMap和beanDefinitionNames中。

@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException {if (beanDefinition instanceof AbstractBeanDefinition) {try {// 注册前的最后一个校验,这里的检验不同于之前的xml文件校验,主要是对应abstractBeanDefinition属性的methodOverrides校验,// 检验methodOverrides是否与工厂方法并存或者methodoverrides对应的方法根本不存在((AbstractBeanDefinition) beanDefinition).validate();}//异常,省略。。}BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);// 处理注册已经注册的beanName情况if (existingDefinition != null) {// 如果对应的beanName已经注册且在配置中配置了bean不允许被覆盖,则抛出异常if (!isAllowBeanDefinitionOverriding()) {throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);}//LOG,省略。。this.beanDefinitionMap.put(beanName, beanDefinition);}else {if (hasBeanCreationStarted()) {// Cannot modify startup-time collection elements anymore (for stable iteration)synchronized (this.beanDefinitionMap) {this.beanDefinitionMap.put(beanName, beanDefinition);List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);updatedDefinitions.addAll(this.beanDefinitionNames);updatedDefinitions.add(beanName);this.beanDefinitionNames = updatedDefinitions;removeManualSingletonName(beanName);}}else {// Still in startup registration phase// 注册beanDefinitionthis.beanDefinitionMap.put(beanName, beanDefinition);// 记录beanNamethis.beanDefinitionNames.add(beanName);removeManualSingletonName(beanName);}this.frozenBeanDefinitionNames = null;}if (existingDefinition != null || containsSingleton(beanName)) {// 重置所有beanName对应的缓存resetBeanDefinition(beanName);}else if (isConfigurationFrozen()) {clearByTypeCache();}}

至此,XML加载整个bean标签流程结束。
在这里插入图片描述

http://www.ahscrl.com/news/12099.html

相关文章:

  • 背景网站建设公司厦门百度快照优化排名
  • 国家车辆保险网站移投界seo
  • 做网站的公司都是小公司找网站公司制作网站
  • 建设网站文献张家口网站seo
  • 定制东莞网站制作公司国际要闻
  • 敦煌手机网站设计行业关键词词库
  • 北京公司网站建设百度权重1是什么意思
  • wordpress 取消注册邮件惠州关键词排名优化
  • 电子商务网站建设感悟推广引流吸引人的文案
  • 常州网站建设平台本地推广平台有哪些
  • 网站支付怎么做安全吗宁德市教育局官网
  • 平安网站做的太差南宁网站建设服务公司
  • 织梦做双语网站电工培训学校
  • 如何建设一个普通网页网站河南网站优化公司
  • 邹城网站建设哪家便宜上海全网营销推广
  • 装修房子的流程和顺序网络优化师是什么工作
  • 个人博客网站模板源码域名比价网
  • 做视频网站采集需要多大的空间成都seo技术经理
  • 设计作品网站有哪些最近国际新闻
  • 通过输入域名访问自己做的网站百度指数数据分析平台官网
  • 石家庄兼职做网站女教师网课入06654侵录屏
  • 广西机场建设公司网站seo案例
  • 广西网站建设服务好色盲怎么治疗
  • 衡水网站建设网络公司淘宝关键词排名查询
  • 卖房网站排名seo引擎搜索
  • 网站怎么进毕节地seo
  • asp购物网站深圳seo秘籍
  • 微网站建设找哪家公司好网络营销的推广手段
  • wordpress店铺模板制作惠州seo整站优化
  • 上海建设交通网站网站维护需要多长时间