Skip to content

Commit 2dc6e37

Browse files
authored
Duplicate ServiceBean Issue (#721)
* Polish #718 : [Samples] Introducing the samples deployed the external Servlet container * Polish #718 : [Samples] Introducing the samples deployed the external Servlet container * Polish #718 : [Samples] Introducing the samples deployed the external Servlet container * Polish #685 : Dubbo2.7.5: Duplicate ServiceBean found
1 parent 611fafe commit 2dc6e37

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

dubbo-spring-boot-compatible/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboAutoConfiguration.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.apache.dubbo.config.spring.beans.factory.annotation.ServiceClassPostProcessor;
2424
import org.apache.dubbo.config.spring.context.annotation.DubboConfigConfiguration;
2525
import org.apache.dubbo.config.spring.context.annotation.EnableDubboConfig;
26+
import org.apache.dubbo.spring.boot.beans.factory.config.ServiceBeanIdConflictProcessor;
2627

2728
import org.springframework.beans.factory.annotation.Autowired;
2829
import org.springframework.beans.factory.annotation.Qualifier;
@@ -61,6 +62,7 @@
6162
@Configuration
6263
@AutoConfigureAfter(DubboRelaxedBindingAutoConfiguration.class)
6364
@EnableConfigurationProperties(DubboConfigurationProperties.class)
65+
@Import(ServiceBeanIdConflictProcessor.class)
6466
public class DubboAutoConfiguration {
6567

6668
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.dubbo.spring.boot.beans.factory.config;
18+
19+
import org.apache.dubbo.config.ServiceConfig;
20+
import org.apache.dubbo.config.spring.ServiceBean;
21+
22+
import org.springframework.beans.BeansException;
23+
import org.springframework.beans.factory.DisposableBean;
24+
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
25+
import org.springframework.beans.factory.support.RootBeanDefinition;
26+
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
27+
import org.springframework.core.Ordered;
28+
import org.springframework.core.PriorityOrdered;
29+
30+
import java.util.HashMap;
31+
import java.util.LinkedHashSet;
32+
import java.util.Map;
33+
import java.util.Objects;
34+
import java.util.Set;
35+
36+
import static org.springframework.util.ClassUtils.getUserClass;
37+
import static org.springframework.util.ClassUtils.isAssignable;
38+
39+
/**
40+
* The post-processor for resolving the id conflict of {@link ServiceBean} when an interface is
41+
* implemented by multiple services with different groups or versions that are exported on one provider
42+
* <p>
43+
* Current implementation is a temporary resolution, and will be removed in the future.
44+
*
45+
* @see CommonAnnotationBeanPostProcessor
46+
* @since 2.7.7
47+
* @deprecated
48+
*/
49+
public class ServiceBeanIdConflictProcessor implements MergedBeanDefinitionPostProcessor, DisposableBean, PriorityOrdered {
50+
51+
/**
52+
* The key is the class names of interfaces that were exported by {@link ServiceBean}
53+
* The value is bean names of {@link ServiceBean} or {@link ServiceConfig}.
54+
*/
55+
private Map<String, String> interfaceNamesToBeanNames = new HashMap<>();
56+
57+
/**
58+
* Holds the bean names of {@link ServiceBean} or {@link ServiceConfig}.
59+
*/
60+
private Set<String> conflictedBeanNames = new LinkedHashSet<>();
61+
62+
@Override
63+
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
64+
// Get raw bean type
65+
Class<?> rawBeanType = getUserClass(beanType);
66+
if (isAssignable(ServiceConfig.class, rawBeanType)) { // ServiceConfig type or sub-type
67+
String interfaceName = (String) beanDefinition.getPropertyValues().get("interface");
68+
String mappedBeanName = interfaceNamesToBeanNames.putIfAbsent(interfaceName, beanName);
69+
// If mapped bean name exists and does not equal current bean name
70+
if (mappedBeanName != null && !mappedBeanName.equals(beanName)) {
71+
// conflictedBeanNames will record current bean name.
72+
conflictedBeanNames.add(beanName);
73+
}
74+
}
75+
}
76+
77+
@Override
78+
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
79+
if (conflictedBeanNames.contains(beanName) && bean instanceof ServiceConfig) {
80+
ServiceConfig serviceConfig = (ServiceConfig) bean;
81+
if (isConflictedServiceConfig(serviceConfig)) {
82+
// Set id as the bean name
83+
serviceConfig.setId(beanName);
84+
}
85+
86+
}
87+
return bean;
88+
}
89+
90+
private boolean isConflictedServiceConfig(ServiceConfig serviceConfig) {
91+
return Objects.equals(serviceConfig.getId(), serviceConfig.getInterface());
92+
}
93+
94+
@Override
95+
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
96+
return bean;
97+
}
98+
99+
/**
100+
* Keep the order being higher than {@link CommonAnnotationBeanPostProcessor#getOrder()} that is
101+
* {@link Ordered#LOWEST_PRECEDENCE}
102+
*
103+
* @return {@link Ordered#LOWEST_PRECEDENCE} +1
104+
*/
105+
@Override
106+
public int getOrder() {
107+
return LOWEST_PRECEDENCE + 1;
108+
}
109+
110+
@Override
111+
public void destroy() throws Exception {
112+
interfaceNamesToBeanNames.clear();
113+
conflictedBeanNames.clear();
114+
}
115+
}

0 commit comments

Comments
 (0)