1
0
mirror of https://gitee.com/mirrors/Spring-Cloud-Alibaba.git synced 2021-06-26 13:25:11 +08:00

Temporary commit

This commit is contained in:
mercyblitz 2019-01-19 11:54:45 +08:00
parent 26a05cbefb
commit f34e1883e3
8 changed files with 297 additions and 174 deletions

View File

@ -0,0 +1,96 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.alibaba.dubbo.autoconfigure;
import feign.Feign;
import feign.RequestInterceptor;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.cloud.alibaba.dubbo.openfeign.DubboFeignClientsConfiguration;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.cloud.openfeign.FeignContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
import java.util.LinkedHashSet;
import java.util.Set;
import static org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboOpenFeignAutoConfiguration.FEIGN_CLIENT_FACTORY_BEAN_CLASS_NAME;
/**
* Dubbo Feign Auto-{@link Configuration Configuration}
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
@ConditionalOnClass(value = Feign.class, name = FEIGN_CLIENT_FACTORY_BEAN_CLASS_NAME)
@EnableFeignClients(defaultConfiguration = DubboFeignClientsConfiguration.class)
@AutoConfigureAfter(FeignAutoConfiguration.class)
@Configuration
public class DubboOpenFeignAutoConfiguration {
static final String FEIGN_CLIENT_FACTORY_BEAN_CLASS_NAME =
"org.springframework.cloud.openfeign.FeignClientFactoryBean";
@Autowired
private ObjectProvider<FeignContext> feignContextObjectProvider;
@EventListener(ApplicationReadyEvent.class)
public void onContextRefreshed(ApplicationReadyEvent event) {
ConfigurableApplicationContext applicationContext = event.getApplicationContext();
// Resolve the subscribed service names for @FeignClient
Set<String> feignClientServiceNames = resolveFeignClientServiceNames(applicationContext);
// FeignContext
FeignContext feignContext = feignContextObjectProvider.getIfAvailable();
}
/**
* Resolve the subscribed service names for @FeignClient
*
* @param applicationContext Current {@link ConfigurableApplicationContext}
* @return non-null {@link Set}
*/
private Set<String> resolveFeignClientServiceNames(ConfigurableApplicationContext applicationContext) {
Set<String> feignClientServiceNames = new LinkedHashSet<>();
ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
if (FEIGN_CLIENT_FACTORY_BEAN_CLASS_NAME.equals(beanDefinition.getBeanClassName())) {
String feignClientServiceName = (String) beanDefinition.getPropertyValues().get("name");
feignClientServiceNames.add(feignClientServiceName);
}
}
return feignClientServiceNames;
}
@Bean
public RequestInterceptor requestInterceptor() {
return template -> {
System.out.println(template);
};
}
}

View File

@ -19,8 +19,8 @@ package org.springframework.cloud.alibaba.dubbo.autoconfigure;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.alibaba.dubbo.rest.feign.RestMetadataConfigService;
import org.springframework.cloud.alibaba.dubbo.rest.feign.RestMetadataResolver;
import org.springframework.cloud.alibaba.dubbo.util.MetadataConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
@ -46,7 +46,8 @@ public class DubboRestAutoConfiguration {
}
@Bean
public MetadataConfigUtils metadataConfigUtils() {
return new MetadataConfigUtils();
public RestMetadataConfigService restMetadataConfigService() {
return new RestMetadataConfigService();
}
}

View File

@ -20,42 +20,28 @@ import com.alibaba.boot.dubbo.autoconfigure.DubboAutoConfiguration;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.ReferenceBean;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.Client;
import feign.Request;
import feign.RequestInterceptor;
import feign.Response;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.alibaba.dubbo.rest.feign.RestMetadataConfigService;
import org.springframework.cloud.alibaba.dubbo.rest.feign.RestMetadataResolver;
import org.springframework.cloud.alibaba.dubbo.rest.metadata.ServiceRestMetadata;
import org.springframework.cloud.alibaba.dubbo.util.MetadataConfigUtils;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent;
import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.cloud.context.named.NamedContextFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* The Auto-Configuration class for Dubbo REST Discovery
@ -70,6 +56,9 @@ import java.util.Set;
@Configuration
public class DubboRestDiscoveryAutoConfiguration {
private static final String FEIGN_CLIENT_FACTORY_BEAN_CLASS_NAME =
"org.springframework.cloud.openfeign.FeignClientFactoryBean";
@Autowired
private DiscoveryClient discoveryClient;
@ -94,119 +83,7 @@ public class DubboRestDiscoveryAutoConfiguration {
private String nacosServerAddress;
@Autowired
private ListableBeanFactory beanFactory;
@Autowired
private MetadataConfigUtils metadataConfigUtils;
/**
* Handle on self instance registered.
*
* @param event {@link InstanceRegisteredEvent}
*/
@EventListener(InstanceRegisteredEvent.class)
public void onSelfInstanceRegistered(InstanceRegisteredEvent event) throws Exception {
Class<?> targetClass = AbstractAutoServiceRegistration.class;
Object source = event.getSource();
if (!targetClass.isInstance(source)) {
return;
}
// getRegistration() is a protected method
Method method = targetClass.getDeclaredMethod("getRegistration");
method.setAccessible(true);
Registration registration = (Registration) ReflectionUtils.invokeMethod(method, source);
String serviceRestMetaData =
metadataConfigUtils.getServiceRestMetadata(registration.getServiceId());
Set<ServiceRestMetadata> metadata = objectMapper.readValue(serviceRestMetaData, Set.class);
System.out.println(serviceRestMetaData);
}
@Bean
public RequestInterceptor requestInterceptor() {
return template -> {
System.out.println(template);
};
}
private void noop() {
Map<String, NamedContextFactory.Specification> specifications =
beanFactory.getBeansOfType(NamedContextFactory.Specification.class);
// 1. Get all service names from Spring beans that was annotated by @FeignClient
List<String> serviceNames = new LinkedList<>();
specifications.forEach((beanName, specification) ->
{
String serviceName = beanName.substring(0, beanName.indexOf("."));
serviceNames.add(serviceName);
// 2. Get all service instances by echo specified service name
List<ServiceInstance> serviceInstances = discoveryClient.getInstances(serviceName);
if (!serviceInstances.isEmpty()) {
ServiceInstance serviceInstance = serviceInstances.get(0);
// 3. Get Rest metadata from service instance
Map<String, String> metadata = serviceInstance.getMetadata();
// 4. Resolve REST metadata from the @FeignClient instance
String restMetadataJson = metadata.get("restMetadata");
/**
* {
* "providers:org.springframework.cloud.alibaba.dubbo.service.EchoService:1.0.0": [
* "{\"method\":\"POST\",\"url\":\"/plus?a={a}&b={b}\",\"headers\":{}}",
* "{\"method\":\"GET\",\"url\":\"/echo?message={message}\",\"headers\":{}}"
* ]
* }
*/
try {
Map<String, List<String>> restMetadata = objectMapper.readValue(restMetadataJson, Map.class);
restMetadata.forEach((dubboServiceName, restJsons) -> {
restJsons.stream().map(restMetadataResolver::resolveRequest).forEach(request -> {
referenceBeanCache.put(request.toString(), buildReferenceBean(dubboServiceName));
});
});
} catch (IOException e) {
throw new RuntimeException(e);
}
//
}
});
}
private ReferenceBean buildReferenceBean(ServiceInstance serviceInstance) {
ReferenceBean referenceBean = new ReferenceBean();
Map<String, String> metadata = serviceInstance.getMetadata();
// 4. Resolve REST metadata from the @FeignClient instance
String restMetadataJson = metadata.get("restMetadata");
try {
Map<String, List<String>> restMetadata = objectMapper.readValue(restMetadataJson, Map.class);
restMetadata.forEach((dubboServiceName, restJsons) -> {
restJsons.stream().map(restMetadataResolver::resolveRequest).forEach(request -> {
referenceBeanCache.put(request.toString(), buildReferenceBean(dubboServiceName));
});
});
} catch (IOException e) {
throw new RuntimeException(e);
}
return referenceBean;
}
private RestMetadataConfigService restMetadataConfigService;
private ReferenceBean buildReferenceBean(String dubboServiceName) {
ReferenceBean referenceBean = new ReferenceBean();
@ -271,10 +148,122 @@ public class DubboRestDiscoveryAutoConfiguration {
}
@EventListener(ContextRefreshedEvent.class)
public void onContextRefreshed(ContextRefreshedEvent event) {
}
}
// private Method getRegistrationMethod;
//
// @PostConstruct
// public void init() throws NoSuchMethodException {
// getRegistrationMethod = initGetRegistrationMethod();
// }
//
// /**
// * Initializes {@link AbstractAutoServiceRegistration#getRegistration() getRegistration method} that is is protected.
// *
// * @return {@link Method}
// * @throws NoSuchMethodException
// */
// private Method initGetRegistrationMethod() throws NoSuchMethodException {
// Method method = AbstractAutoServiceRegistration.class.getDeclaredMethod("getRegistration");
// method.setAccessible(true);
// return method;
// }
//
// private Registration getRegistration(AbstractAutoServiceRegistration source) {
// return (Registration) ReflectionUtils.invokeMethod(getRegistrationMethod, source);
// }
//
// private void noop() {
// Map<String, NamedContextFactory.Specification> specifications =
// beanFactory.getBeansOfType(NamedContextFactory.Specification.class);
// // 1. Get all service names from Spring beans that was annotated by @FeignClient
// List<String> serviceNames = new LinkedList<>();
//
// specifications.forEach((beanName, specification) ->
//
// {
// String serviceName = beanName.substring(0, beanName.indexOf("."));
// serviceNames.add(serviceName);
//
// // 2. Get all service instances by echo specified service name
// List<ServiceInstance> serviceInstances = discoveryClient.getInstances(serviceName);
// if (!serviceInstances.isEmpty()) {
// ServiceInstance serviceInstance = serviceInstances.get(0);
// // 3. Get Rest metadata from service instance
// Map<String, String> metadata = serviceInstance.getMetadata();
// // 4. Resolve REST metadata from the @FeignClient instance
// String restMetadataJson = metadata.get("restMetadata");
// /**
// * {
// * "providers:org.springframework.cloud.alibaba.dubbo.service.EchoService:1.0.0": [
// * "{\"method\":\"POST\",\"url\":\"/plus?a={a}&b={b}\",\"headers\":{}}",
// * "{\"method\":\"GET\",\"url\":\"/echo?message={message}\",\"headers\":{}}"
// * ]
// * }
// */
// try {
// Map<String, List<String>> restMetadata = objectMapper.readValue(restMetadataJson, Map.class);
//
// restMetadata.forEach((dubboServiceName, restJsons) -> {
// restJsons.stream().map(restMetadataResolver::resolveRequest).forEach(request -> {
// referenceBeanCache.put(request.toString(), buildReferenceBean(dubboServiceName));
// });
// });
//
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
//
// //
// }
// });
// }
//
// private ReferenceBean buildReferenceBean(ServiceInstance serviceInstance) {
//
// ReferenceBean referenceBean = new ReferenceBean();
// Map<String, String> metadata = serviceInstance.getMetadata();
// // 4. Resolve REST metadata from the @FeignClient instance
// String restMetadataJson = metadata.get("restMetadata");
//
// try {
// Map<String, List<String>> restMetadata = objectMapper.readValue(restMetadataJson, Map.class);
//
// restMetadata.forEach((dubboServiceName, restJsons) -> {
// restJsons.stream().map(restMetadataResolver::resolveRequest).forEach(request -> {
// referenceBeanCache.put(request.toString(), buildReferenceBean(dubboServiceName));
// });
// });
//
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
//
// return referenceBean;
// }
// /**
// * Handle on self instance registered.
// *
// * @param event {@link InstanceRegisteredEvent}
// */
// @EventListener(InstanceRegisteredEvent.class)
// public void onSelfInstanceRegistered(InstanceRegisteredEvent event) throws Exception {
//
// Class<?> targetClass = AbstractAutoServiceRegistration.class;
//
// Object source = event.getSource();
//
// Assert.isInstanceOf(targetClass, source,
// format("The source of %s must implement %s", source, targetClass.getName()));
//
// Registration registration = getRegistration((AbstractAutoServiceRegistration) source);
//
// String serviceRestMetaDataConfig =
// restMetadataConfigService.getServiceRestMetadata(registration.getServiceId());
//
// Set<ServiceRestMetadata> serviceRestMetadata = objectMapper.readValue(serviceRestMetaDataConfig,
// TypeFactory.defaultInstance().constructCollectionType(Set.class, ServiceRestMetadata.class));
//
// }

View File

@ -20,21 +20,18 @@ import com.alibaba.dubbo.config.spring.ServiceBean;
import com.alibaba.dubbo.config.spring.context.event.ServiceBeanExportedEvent;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.alibaba.dubbo.rest.feign.RestMetadataConfigService;
import org.springframework.cloud.alibaba.dubbo.rest.feign.RestMetadataResolver;
import org.springframework.cloud.alibaba.dubbo.rest.metadata.ServiceRestMetadata;
import org.springframework.cloud.alibaba.dubbo.util.MetadataConfigUtils;
import org.springframework.cloud.client.discovery.event.InstancePreRegisteredEvent;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
@ -48,18 +45,14 @@ import java.util.Set;
@AutoConfigureAfter(value = {
DubboRestAutoConfiguration.class, DubboServiceRegistrationAutoConfiguration.class})
@Configuration
public class DubboRestMetadataRegistrationAutoConfiguration implements BeanClassLoaderAware {
public class DubboRestMetadataRegistrationAutoConfiguration {
/**
* A Map to store REST metadata temporary, its' key is the special service name for a Dubbo service,
* the value is a JSON content of JAX-RS or Spring MVC REST metadata from the annotated methods.
*/
private final Map<String, Map<String, Map<String, Object>>> restMetadata = new LinkedHashMap<>();
private final Set<ServiceRestMetadata> serviceRestMetadata = new LinkedHashSet<>();
private ClassLoader classLoader;
@Autowired
private ObjectMapper objectMapper;
@ -67,14 +60,12 @@ public class DubboRestMetadataRegistrationAutoConfiguration implements BeanClass
private RestMetadataResolver restMetadataResolver;
@Autowired
private MetadataConfigUtils metadataConfigUtils;
private RestMetadataConfigService metadataConfigService;
@EventListener(ServiceBeanExportedEvent.class)
public void recordRestMetadata(ServiceBeanExportedEvent event) throws JsonProcessingException {
ServiceBean serviceBean = event.getServiceBean();
// Map<String, Map<String, Map<String, Object>>> metadata = restMetadataResolver.resolve(serviceBean);
// restMetadata.putAll(metadata);
serviceRestMetadata.addAll(restMetadataResolver.resolve(serviceBean));
}
@ -93,15 +84,8 @@ public class DubboRestMetadataRegistrationAutoConfiguration implements BeanClass
String restMetadataJson = objectMapper.writeValueAsString(serviceRestMetadata);
metadataConfigUtils.publishServiceRestMetadata(registration.getServiceId(), restMetadataJson);
metadataConfigService.publishServiceRestMetadata(registration.getServiceId(), restMetadataJson);
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
}

View File

@ -0,0 +1,56 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.alibaba.dubbo.openfeign;
import feign.Feign;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboOpenFeignAutoConfiguration;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
/**
* Dubbo {@link Configuration} for {@link FeignClient FeignClients}
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
* @see DubboOpenFeignAutoConfiguration
* @see org.springframework.cloud.openfeign.FeignContext#setConfigurations(List)
* @see FeignClientsConfiguration
*/
@Configuration
public class DubboFeignClientsConfiguration {
@Bean
public BeanPostProcessor beanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof Feign.Builder) {
Feign.Builder builder = (Feign.Builder) bean;
Feign feign = builder.build();
}
return bean;
}
};
}
}

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.alibaba.dubbo.util;
package org.springframework.cloud.alibaba.dubbo.rest.feign;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
@ -26,9 +26,9 @@ import javax.annotation.PostConstruct;
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
/**
* TODO
* Rest Metadata Config Service
*/
public class MetadataConfigUtils {
public class RestMetadataConfigService {
@Autowired
private NacosConfigProperties nacosConfigProperties;

View File

@ -1,5 +1,6 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboRestAutoConfiguration,\
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboOpenFeignAutoConfiguration,\
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration,\
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboRestMetadataRegistrationAutoConfiguration,\
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboRestDiscoveryAutoConfiguration

View File

@ -22,21 +22,17 @@ import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.spring.ReferenceBean;
import com.alibaba.dubbo.config.spring.ServiceBean;
import com.alibaba.dubbo.config.spring.context.event.ServiceBeanExportedEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.alibaba.dubbo.service.EchoService;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@ -71,15 +67,15 @@ public class DubboSpringCloudBootstrap {
String echo(@RequestParam("message") String message);
}
@Bean
public ApplicationRunner applicationRunner() {
return arguments -> {
// Dubbo Service call
System.out.println(echoService.echo("mercyblitz"));
// Spring Cloud Open Feign REST Call
System.out.println(feignEchoService.echo("mercyblitz"));
};
}
// @Bean
// public ApplicationRunner applicationRunner() {
// return arguments -> {
// // Dubbo Service call
// System.out.println(echoService.echo("mercyblitz"));
// // Spring Cloud Open Feign REST Call
// System.out.println(feignEchoService.echo("mercyblitz"));
// };
// }
@Autowired