現象 應用任務運行異常
{code}Caused by: java.lang.IllegalStateException: Duplicate spring bean id realnameAuthPubService at com.alibaba.dubbo.rpc.config.spring.schema.DubboBeanDefinitionParser.parse(DubboBeanDefinitionParser.java:87) at com.alibaba.dubbo.rpc.config.spring.schema.DubboBeanDefinitionParser.parse(DubboBeanDefinitionParser.java:63) at org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:69) at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1297) at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1287) at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:135) at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:92) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:507) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:398){code}
排查
查看代碼,確實有id為realnameAuthPubService的重複配置,不過已經存在很久了,之前都沒有問題。
問題出現的當天僅有dubbo升級需求發布,所以定位到是dubbo升級引發了這個一直存在的問題
原因
spring對於id重複的預設處理策略是覆蓋,如DefaultListableBeanFactory.registerBeanDefinition,dubbo之前沒做特殊處理,所以對重複的id會覆蓋,所以一直沒有報錯
{code}...synchronized (this.beanDefinitionMap) {Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);if (oldBeanDefinition != null) { ##allowBeanDefinitionOverriding預設值為tureif (!this.allowBeanDefinitionOverriding) {throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +"': There is already [" + oldBeanDefinition + "] bound.");}else {if (this.logger.isInfoEnabled()) {this.logger.info("Overriding bean definition for bean '" + beanName +"': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");}}}else {this.beanDefinitionNames.add(beanName);this.frozenBeanDefinitionNames = null;} ##如果原來有,覆蓋this.beanDefinitionMap.put(beanName, beanDefinition);...{code}
dubbo的新版本對重複的id做了特殊處理,如果有重複直接拋異常,所以出現問題
{code}DubboBeanDefinitionParser.parse private BeanDefinition parse(Element element, ParserContext parserContext, Class<?> beanClass, boolean required) { ... if (id != null && id.length() > 0) { ###判斷是否已經存在,存在則拋出異常 if (parserContext.getRegistry().containsBeanDefinition(id)) { throw new IllegalStateException("Duplicate spring bean id " + id); } parserContext.getRegistry().registerBeanDefinition(id, beanDefinition); } ... }{code}