您好,登錄后才能下訂單哦!
這篇文章主要講解了“Spring實(shí)現(xiàn)解析默認(rèn)標(biāo)簽的方法”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“Spring實(shí)現(xiàn)解析默認(rèn)標(biāo)簽的方法”吧!
parseDefaultElement(ele, delegate); void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { //解析import標(biāo)簽 if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } //解析alias標(biāo)簽 else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } //解析bean標(biāo)簽 else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); } //解析beans標(biāo)簽,遞歸處理 else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { doRegisterBeanDefinitions(ele); } } protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { //1.委托BeanDefinitionPaserDelegate類進(jìn)行元素解析,將BeanDefinition封裝進(jìn)BeanDefinitionHolder里面 //包含class、name、id屬性 BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { //2.若默認(rèn)標(biāo)簽的子節(jié)點(diǎn)下有自定義屬性,還需要再對(duì)自定義標(biāo)簽解析 bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { //3.委托BeanDefinitionReaderUtils注冊(cè) BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } //4.發(fā)出響應(yīng)事件,通知想關(guān)心的監(jiān)聽(tīng)事件 getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } }
BeanDefinition是一個(gè)接口,其抽象實(shí)現(xiàn)類為AbstractBeanDefinition,有三個(gè)子類,分別為RootBeanDefinition、ChildBeanDefinition 和GenericBeanDefinition. BeanDefinition是配置文件bean元素在容器中的內(nèi)部表現(xiàn)形式,和bean中屬性一一對(duì)應(yīng).Spring通過(guò) BeanDefinition將配置文件中的bean配置信息轉(zhuǎn)換為容器的內(nèi)部表示,并將這些信息注冊(cè)到BeanDefinitionRegistry中,它就是Spring 配置信息的內(nèi)存數(shù)據(jù)庫(kù),是一個(gè)Map,后續(xù)操作直接從該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<String> aliases = new ArrayList<String>(); if (StringUtils.hasLength(nameAttr)) { String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS); aliases.addAll(Arrays.asList(nameArr)); } String beanName = id; //若沒(méi)有指定id屬性,使用別名的第一個(gè)代替 if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) { beanName = aliases.remove(0); } if (containingBean == null) { checkNameUniqueness(beanName, aliases, ele); } //進(jìn)一步解析其他所有屬性并封裝到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); } //創(chuàng)建用于承載屬性的GenericBeanDefinition,直接new的,并set傳進(jìn)去的參數(shù) AbstractBeanDefinition bd = createBeanDefinition(className, parent); //1.硬編碼解析bean的各種屬性 parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); //2.解析description bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT)); //3.解析元數(shù)據(jù) parseMetaElements(ele, bd); //4.解析lookup-method屬性,見(jiàn)附錄1,實(shí)際要返回的bean是在配置文件里面配置的 parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); //5.解析replace-method屬性,不但可以動(dòng)態(tài)地替換返回實(shí)體的bean,而且還能動(dòng)態(tài)地更改原有方法的邏輯 parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); //6.解析構(gòu)造函數(shù)參數(shù),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屬性,若不設(shè)置或者設(shè)置成其他字符都會(huì)設(shè)置為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:見(jiàn)附錄1、2 步驟6:解析構(gòu)造函數(shù)參數(shù)
上述解析后的數(shù)據(jù)都放在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; //構(gòu)造函數(shù)屬性 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; //是否執(zhí)行init-method和destroy-method private boolean enforceInitMethod = true; private boolean enforceDestroyMethod = true; }
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { //解析BeanDefinition BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { //注冊(cè)BeanDefinition到registry BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } //通知監(jiān)聽(tīng)器解析及完成注冊(cè),當(dāng)程序開(kāi)發(fā)人員需要對(duì)注冊(cè)BeanDefinition事件進(jìn)行監(jiān)聽(tīng)時(shí)可以通過(guò)注冊(cè)監(jiān)聽(tīng)器的方 //式并將處理邏輯寫入監(jiān)聽(tīng)器中,目前Spring中沒(méi)有對(duì)此事件做任何邏輯處理 getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } }
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry){ String beanName = definitionHolder.getBeanName(); //使用beanName做唯一標(biāo)識(shí)注冊(cè) registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String aliase : aliases) { //使用別名做注冊(cè) registry.registerAlias(beanName, aliase); } } }
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { if (beanDefinition instanceof AbstractBeanDefinition) { try { //做校驗(yàn),拋異常部分已刪除 ((AbstractBeanDefinition) beanDefinition).validate(); } } //beanDefinitionMap就是存放注冊(cè)信息的全局變量,會(huì)存在并發(fā)訪問(wèn)的情況,加鎖,它是ConcurrentHashMap //Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(64); synchronized (this.beanDefinitionMap) { Object oldBeanDefinition = this.beanDefinitionMap.get(beanName); //處理已經(jīng)注冊(cè)beanName的情況 if (oldBeanDefinition != null) { if (!this.allowBeanDefinitionOverriding) { //此處代碼簡(jiǎn)略了,不允許覆蓋則拋異常,允許覆蓋則記錄下日志 } } else { this.beanDefinitionNames.add(beanName); this.frozenBeanDefinitionNames = null; } //真正進(jìn)行注冊(cè) this.beanDefinitionMap.put(beanName, beanDefinition); } //清除緩存 resetBeanDefinition(beanName); }
protected void processAliasRegistration(Element ele) { //獲取beanName String name = ele.getAttribute(NAME_ATTRIBUTE); //獲取別名alias String alias = ele.getAttribute(ALIAS_ATTRIBUTE); boolean valid = true; //之前有一些校驗(yàn),刪掉了 if (valid) { try { //注冊(cè) getReaderContext().getRegistry().registerAlias(name, alias); } getReaderContext().fireAliasRegistered(name, alias, extractSource(ele)); } }
protected void importBeanDefinitionResource(Element ele) { //解析resource屬性,形如<import resource=”***.xml”/> 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<Resource> actualResources = new LinkedHashSet<Resource>(4); //判斷是相對(duì)路徑還是絕對(duì)路徑 boolean absoluteLocation = false; try { absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute(); } if (absoluteLocation) { try { //是絕對(duì)路徑,直接調(diào)用loadBeanDefinitions加載BeanDefinition,遞歸操作 int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources); } }else { try { int importCount; //計(jì)算出絕對(duì)路徑,進(jìn)行l(wèi)oadBeanDefinitons 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(); }
<bean id="getBeanTest" class="com.lwh.spring.look.GetBeanTest"> <lookup-method name="getBean" bean="teacher"/> </bean> <bean id="teacher" class="com.lwh.spring.look.Teacher"/>
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; } }
<bean id="testChangeMethod" class="com.lwh.spring.replace.TestChangeMethod"> <replaced-method name="changeMe" replacer="replacer"/> </bean> <bean id="replacer" class="com.lwh.spring.replace.TestMethodReplacer"/>
public void parseReplacedMethodSubElements(Element beanEle, MethodOverrides overrides) { NodeList nl = beanEle.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); //僅當(dāng)在Spring默認(rèn)bean的子元素下且為replace-method時(shí)才有效 if (isCandidateElement(node) && nodeNameEquals(node, REPLACED_METHOD_ELEMENT)) { Element replacedMethodEle = (Element) node; //提取要替換的舊的方法,changeMe String name = replacedMethodEle.getAttribute(NAME_ATTRIBUTE); //提取對(duì)應(yīng)的新的替換方法,replacer String callback = replacedMethodEle.getAttribute(REPLACER_ATTRIBUTE); ReplaceOverride replaceOverride = new ReplaceOverride(name, callback); // Look for arg-type match elements. List<Element> argTypeEles = DomUtils.getChildElementsByTagName(replacedMethodEle, ARG_TYPE_ELEMENT); for (Element argTypeEle : argTypeEles) { //記錄參數(shù) 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實(shí)現(xiàn)解析默認(rèn)標(biāo)簽的方法”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)Spring實(shí)現(xiàn)解析默認(rèn)標(biāo)簽的方法這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。