千家信息网

Spring实现解析默认标签的方法

发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,这篇文章主要讲解了"Spring实现解析默认标签的方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Spring实现解析默认标签的方法"吧!1、解析默
千家信息网最后更新 2025年02月02日Spring实现解析默认标签的方法

这篇文章主要讲解了"Spring实现解析默认标签的方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Spring实现解析默认标签的方法"吧!

1、解析默认标签

parseDefaultElement(ele, delegate);void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {   //解析import标签   if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {      importBeanDefinitionResource(ele);   }   //解析alias标签   else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {      processAliasRegistration(ele);   }    //解析bean标签   else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {      processBeanDefinition(ele, delegate);   }   //解析beans标签,递归处理   else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {      doRegisterBeanDefinitions(ele);   }}protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {   //1.委托BeanDefinitionPaserDelegate类进行元素解析,将BeanDefinition封装进BeanDefinitionHolder里面   //包含class、name、id属性   BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);   if (bdHolder != null) {      //2.若默认标签的子节点下有自定义属性,还需要再对自定义标签解析      bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);      try {         //3.委托BeanDefinitionReaderUtils注册         BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder,  getReaderContext().getRegistry());      }      //4.发出响应事件,通知想关心的监听事件      getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));   }}

2、解析BeanDefinition

BeanDefinition是一个接口,其抽象实现类为AbstractBeanDefinition,有三个子类,分别为RootBeanDefinition、ChildBeanDefinition和GenericBeanDefinition. BeanDefinition是配置文件bean元素在容器中的内部表现形式,和bean中属性一一对应.Spring通过BeanDefinition将配置文件中的bean配置信息转换为容器的内部表示,并将这些信息注册到BeanDefinitionRegistry中,它就是Spring配置信息的内存数据库,是一个Map,后续操作直接从该BeanDefinitionRegistry中读取配置信息.

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {   return parseBeanDefinitionElement(ele, null);}
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {   //解析id属性   String id = ele.getAttribute(ID_ATTRIBUTE);   //解析name属性   String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);      //若nameAttr不为空,解析别名属性   List aliases = new ArrayList();   if (StringUtils.hasLength(nameAttr)) {      String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);      aliases.addAll(Arrays.asList(nameArr));   }   String beanName = id;   //若没有指定id属性,使用别名的第一个代替   if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {      beanName = aliases.remove(0);   }   if (containingBean == null) {      checkNameUniqueness(beanName, aliases, ele);   }      //进一步解析其他所有属性并封装到beanDefinition中   AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);      if (beanDefinition != null) {      if (!StringUtils.hasText(beanName)) {         try {            if (containingBean != null) {               beanName =                      BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);            }            else {               beanName = this.readerContext.generateBeanName(beanDefinition);                String beanClassName = beanDefinition.getBeanClassName();               if (beanClassName != null &&                     beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&                     !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {                  aliases.add(beanClassName);               }            }         }      }      String[] aliasesArray = StringUtils.toStringArray(aliases);      return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);   }   return null;}
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean) {   String className = null;   //解析className属性   if (ele.hasAttribute(CLASS_ATTRIBUTE)) {      className = ele.getAttribute(CLASS_ATTRIBUTE).trim();   }   try {      String parent = null;      //解析parent属性      if (ele.hasAttribute(PARENT_ATTRIBUTE)) {         parent = ele.getAttribute(PARENT_ATTRIBUTE);      }      //创建用于承载属性的GenericBeanDefinition,直接new的,并set传进去的参数      AbstractBeanDefinition bd = createBeanDefinition(className, parent);      //1.硬编码解析bean的各种属性      parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);      //2.解析description      bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));      //3.解析元数据      parseMetaElements(ele, bd);      //4.解析lookup-method属性,见附录1,实际要返回的bean是在配置文件里面配置的      parseLookupOverrideSubElements(ele, bd.getMethodOverrides());      //5.解析replace-method属性,不但可以动态地替换返回实体的bean,而且还能动态地更改原有方法的逻辑      parseReplacedMethodSubElements(ele, bd.getMethodOverrides());      //6.解析构造函数参数,property元素和qualifier元素      parseConstructorArgElements(ele, bd);      parsePropertyElements(ele, bd);      parseQualifierElements(ele, bd);      bd.setResource(this.readerContext.getResource());      bd.setSource(extractSource(ele));      return bd;   }}
步骤1:硬编码解析bean的各种属性
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String                                                     beanName,BeanDefinition containingBean, AbstractBeanDefinition bd) {   //解析scope属性   if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {      bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));      if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {         error("Specify either 'scope' or 'singleton', not both", ele);      }   }   //解析singleton属性   else if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {      bd.setScope(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)) ?                                                       BeanDefinition.SCOPE_SINGLETON : BeanDefinition.SCOPE_PROTOTYPE);   }   else if (containingBean != null) {      bd.setScope(containingBean.getScope());   }   if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {      bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));   }      //解析lazy-init属性,若不设置或者设置成其他字符都会设置为false   String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);   if (DEFAULT_VALUE.equals(lazyInit)) {      lazyInit = this.defaults.getLazyInit();   }   bd.setLazyInit(TRUE_VALUE.equals(lazyInit));   //解析autowire属性   String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);   bd.setAutowireMode(getAutowireMode(autowire));   String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);   bd.setDependencyCheck(getDependencyCheck(dependencyCheck));   if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {      String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);      bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));   }   String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);   if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {      String candidatePattern = this.defaults.getAutowireCandidates();      if (candidatePattern != null) {         String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);         bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));      }   }   else {      bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));   }   if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {      bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));   }      //解析init-method属性   if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {      String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);      if (!"".equals(initMethodName)) {         bd.setInitMethodName(initMethodName);      }   }   else {      if (this.defaults.getInitMethod() != null) {         bd.setInitMethodName(this.defaults.getInitMethod());         bd.setEnforceInitMethod(false);      }   }      //解析destroy-method属性   if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {      String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);      if (!"".equals(destroyMethodName)) {         bd.setDestroyMethodName(destroyMethodName);      }   }   else {      if (this.defaults.getDestroyMethod() != null) {         bd.setDestroyMethodName(this.defaults.getDestroyMethod());         bd.setEnforceDestroyMethod(false);      }   }   //解析factory-method属性   if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {      bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));   }   //解析factory-bean属性   if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {      bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));   }   return bd;}
步骤4、5:见附录1、2步骤6:解析构造函数参数

3、AbstractBeanDefinition

上述解析后的数据都放在AbstractBeanDefinition中.
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable {   private volatile Object beanClass;   private String scope = SCOPE_DEFAULT;   private boolean singleton = true;   private boolean prototype = false;   private boolean abstractFlag = false;   private boolean lazyInit = false;   private int autowireMode = AUTOWIRE_NO;   private int dependencyCheck = DEPENDENCY_CHECK_NONE;   private String[] dependsOn;   //构造函数属性   private ConstructorArgumentValues constructorArgumentValues;   //普通属性集合   private MutablePropertyValues propertyValues;   //方法重写的持有者,记录lookup-method、replace-method元素   private MethodOverrides methodOverrides = new MethodOverrides();   private String factoryBeanName;   private String factoryMethodName;   private String initMethodName;   private String destroyMethodName;   //是否执行init-method和destroy-method   private boolean enforceInitMethod = true;   private boolean enforceDestroyMethod = true;}

4、注册BeanDefinition

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {   //解析BeanDefinition   BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);   if (bdHolder != null) {      bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);      try {         //注册BeanDefinition到registry         BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());      }      //通知监听器解析及完成注册,当程序开发人员需要对注册BeanDefinition事件进行监听时可以通过注册监听器的方      //式并将处理逻辑写入监听器中,目前Spring中没有对此事件做任何逻辑处理      getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));   }}
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry){   String beanName = definitionHolder.getBeanName();   //使用beanName做唯一标识注册   registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());   String[] aliases = definitionHolder.getAliases();   if (aliases != null) {      for (String aliase : aliases) {         //使用别名做注册         registry.registerAlias(beanName, aliase);      }   }}
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {   if (beanDefinition instanceof AbstractBeanDefinition) {      try {         //做校验,抛异常部分已删除         ((AbstractBeanDefinition) beanDefinition).validate();      }   }   //beanDefinitionMap就是存放注册信息的全局变量,会存在并发访问的情况,加锁,它是ConcurrentHashMap   //Map beanDefinitionMap = new ConcurrentHashMap<>(64);   synchronized (this.beanDefinitionMap) {      Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);      //处理已经注册beanName的情况      if (oldBeanDefinition != null) {         if (!this.allowBeanDefinitionOverriding) {             //此处代码简略了,不允许覆盖则抛异常,允许覆盖则记录下日志         }      }      else {         this.beanDefinitionNames.add(beanName);         this.frozenBeanDefinitionNames = null;      }      //真正进行注册      this.beanDefinitionMap.put(beanName, beanDefinition);   }   //清除缓存   resetBeanDefinition(beanName);}

5、解析alias标签

protected void processAliasRegistration(Element ele) {   //获取beanName   String name = ele.getAttribute(NAME_ATTRIBUTE);   //获取别名alias   String alias = ele.getAttribute(ALIAS_ATTRIBUTE);   boolean valid = true;   //之前有一些校验,删掉了   if (valid) {      try {         //注册         getReaderContext().getRegistry().registerAlias(name, alias);      }      getReaderContext().fireAliasRegistered(name, alias, extractSource(ele));   }}

6、解析import标签

protected void importBeanDefinitionResource(Element ele) {   //解析resource属性,形如   String location = ele.getAttribute(RESOURCE_ATTRIBUTE);   //不存在直接返回   if (!StringUtils.hasText(location)) {      getReaderContext().error("Resource location must not be empty", ele);      return;   }   location = environment.resolveRequiredPlaceholders(location);   Set actualResources = new LinkedHashSet(4);   //判断是相对路径还是绝对路径   boolean absoluteLocation = false;   try {      absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();   }    if (absoluteLocation) {      try {         //是绝对路径,直接调用loadBeanDefinitions加载BeanDefinition,递归操作         int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources);      }   }else {      try {         int importCount;         //计算出绝对路径,进行loadBeanDefinitons         Resource relativeResource = getReaderContext().getResource().createRelative(location);         if (relativeResource.exists()) {            importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource);            actualResources.add(relativeResource);         }         else {            String baseLocation = getReaderContext().getResource().getURL().toString();            importCount = getReaderContext().getReader().loadBeanDefinitions(                  StringUtils.applyRelativePath(baseLocation, location), actualResources);         }      } }   Resource[] actResArray = actualResources.toArray(new Resource[actualResources.size()]);   getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele));}
附录1:解析lookup-method
public class User {    public void showMe(){        System.out.println("I am a User");    }}public class Teacher extends User{    @Override    public void showMe() {        System.out.println("I am a teacher");    }}public abstract class GetBeanTest {    public void showMe(){        this.getBean().showMe();    }    public abstract User getBean();}
    
public void parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides) {   NodeList nl = beanEle.getChildNodes();   for (int i = 0; i < nl.getLength(); i++) {      Node node = nl.item(i);      if (isCandidateElement(node) && nodeNameEquals(node, LOOKUP_METHOD_ELEMENT)){         Element ele = (Element) node;         //获取要修饰的方法         String methodName = ele.getAttribute(NAME_ATTRIBUTE);         //获取配置返回的bean         String beanRef = ele.getAttribute(BEAN_ELEMENT);         LookupOverride override = new LookupOverride(methodName, beanRef);         override.setSource(extractSource(ele));         overrides.addOverride(override);      }   }}

附录2:解析replace-method
public class TestChangeMethod {    public void changeMe(){        System.out.println("changeMe");    }}public class TestMethodReplacer implements MethodReplacer{    public Object reimplement(Object obj, Method method, Object[] args) throws Throwable {        System.out.println("我替换了原有的方法");        return null;    }}
    
public void parseReplacedMethodSubElements(Element beanEle, MethodOverrides overrides) {   NodeList nl = beanEle.getChildNodes();   for (int i = 0; i < nl.getLength(); i++) {      Node node = nl.item(i);      //仅当在Spring默认bean的子元素下且为replace-method时才有效      if (isCandidateElement(node) && nodeNameEquals(node, REPLACED_METHOD_ELEMENT)) {         Element replacedMethodEle = (Element) node;         //提取要替换的旧的方法,changeMe         String name = replacedMethodEle.getAttribute(NAME_ATTRIBUTE);         //提取对应的新的替换方法,replacer         String callback = replacedMethodEle.getAttribute(REPLACER_ATTRIBUTE);         ReplaceOverride replaceOverride = new ReplaceOverride(name, callback);                  // Look for arg-type match elements.         List argTypeEles = DomUtils.getChildElementsByTagName(replacedMethodEle, ARG_TYPE_ELEMENT);         for (Element argTypeEle : argTypeEles) {            //记录参数            String match = argTypeEle.getAttribute(ARG_TYPE_MATCH_ATTRIBUTE);            match = (StringUtils.hasText(match) ? match : DomUtils.getTextValue(argTypeEle));            if (StringUtils.hasText(match)) {               replaceOverride.addTypeIdentifier(match);            }         }         replaceOverride.setSource(extractSource(replacedMethodEle));         overrides.addOverride(replaceOverride);      }   }}

感谢各位的阅读,以上就是"Spring实现解析默认标签的方法"的内容了,经过本文的学习后,相信大家对Spring实现解析默认标签的方法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

属性 标签 方法 配置 元素 信息 监听 事件 别名 参数 路径 附录 处理 函数 就是 情况 数据 文件 步骤 监听器 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 数据库访问失败 邮箱pop服务器地址 网络安全等级测评行业 数据库管理采用几级模型 软件开发服务研发服务 软件开发过程模型有哪几种 南京进口软件开发资费 关于网络安全我参与的手抄报 计算机网络技术高职教材 软件开发项目实施原则 网络安全就业培训学校 裸金属服务器网卡不发送dhcp 社区版国产数据库 c 加载数据库文件路径 华为基于鲲鹏处理器的服务器 淘宝店发货怎么需要购买服务器 计算机网络技术去哪里实习 多部委发布网络安全审查办法 上海安全接入服务器在哪 边锋网络技术有限公司官网 数据库安全检查 网络安全招聘面试试题 参观郑州网络安全科技馆 网络工程与软件开发哪个学校好 如何实现数据库安全控制 1u服务器适合做家用服务器么 常见的应用服务器有哪几个 邮政成本四大数据库有哪些 中国人民大学网络安全与执法 浙大数据库技术作业
0