Spring实现解析默认标签的方法
发表于:2025-12-03 作者:千家信息网编辑
千家信息网最后更新 2025年12月03日,这篇文章主要讲解了"Spring实现解析默认标签的方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Spring实现解析默认标签的方法"吧!1、解析默
千家信息网最后更新 2025年12月03日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安全错误
数据库的锁怎样保障安全
上海服务器风扇批发
宝山区专业性网络技术中心收费
海南 网络安全 招聘
和平区好的软件开发哪家强
上海黑犇互联网科技值得去
未转变者连接不上服务器怎么办
教学管理数据库设置什么最好
云浮软件开发好不好
河南软件开发品质保障
数据库查询的关系运算
精通收银数据库
全球软件开发大会 2016
网络安全就学防火墙有什么用
网络安全系统设置教程
网络安全和网络建设专科
怎么把游戏服务器时间改了
数据库远程调用失败怎么办
密太数据库
软件开发需要动脑吗
电商后台管理系统数据库需求分析
圣诞铃声软件开发
四川淘天下网络技术有限公司
文档管理软件开发
数据库多例 会存在什么问题
宜宾展厅互动软件开发公司
csgo服务器目前负载过
女生网络安全
上海日尤客网络技术公司简介
印象笔记国际版服务器在哪
网络技术ps