1
0
mirror of https://gitee.com/mirrors/Spring-Cloud-Alibaba.git synced 2021-06-26 13:25:11 +08:00
This commit is contained in:
mercyblitz 2019-02-20 01:31:22 +08:00
parent d05c437d89
commit c0430abcae
13 changed files with 393 additions and 109 deletions

View File

@ -27,15 +27,19 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.cloud.alibaba.dubbo.annotation.DubboTransported;
import org.springframework.cloud.alibaba.dubbo.client.loadbalancer.DubboAdapterLoadBalancerInterceptor;
import org.springframework.cloud.alibaba.dubbo.metadata.DubboTransportedMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository;
import org.springframework.cloud.alibaba.dubbo.metadata.service.DubboGenericServiceFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor;
import org.springframework.cloud.client.loadbalancer.RestTemplateCustomizer;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
import org.springframework.core.env.Environment;
import org.springframework.core.type.MethodMetadata;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
@ -66,6 +70,12 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClass
@Autowired
private ConfigurableListableBeanFactory beanFactory;
@Autowired
private DubboGenericServiceFactory dubboGenericServiceFactory;
@Autowired
private Environment environment;
@LoadBalanced
@Autowired(required = false)
private Map<String, RestTemplate> restTemplates = Collections.emptyMap();
@ -82,28 +92,30 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClass
public void adaptRestTemplates() {
for (Map.Entry<String, RestTemplate> entry : restTemplates.entrySet()) {
String beanName = entry.getKey();
if (isDubboTranslatedAnnotated(beanName)) {
adaptRestTemplate(entry.getValue());
Map<String, Object> dubboTranslatedAttributes = getDubboTranslatedAttributes(beanName);
if (!CollectionUtils.isEmpty(dubboTranslatedAttributes)) {
adaptRestTemplate(entry.getValue(), dubboTranslatedAttributes);
}
}
}
/**
* Judge {@link RestTemplate} bean being annotated {@link DubboTransported @DubboTransported} or not
* Gets the annotation attributes {@link RestTemplate} bean being annotated
* {@link DubboTransported @DubboTransported}
*
* @param beanName the bean name of {@link LoadBalanced @LoadBalanced} {@link RestTemplate}
* @return
* @return non-null {@link Map}
*/
private boolean isDubboTranslatedAnnotated(String beanName) {
boolean annotated = false;
private Map<String, Object> getDubboTranslatedAttributes(String beanName) {
Map<String, Object> attributes = Collections.emptyMap();
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
if (beanDefinition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annotatedBeanDefinition = (AnnotatedBeanDefinition) beanDefinition;
MethodMetadata factoryMethodMetadata = annotatedBeanDefinition.getFactoryMethodMetadata();
annotated = factoryMethodMetadata != null &&
!factoryMethodMetadata.getAnnotationAttributes(DUBBO_TRANSPORTED_CLASS_NAME).isEmpty();
attributes = factoryMethodMetadata != null ?
factoryMethodMetadata.getAnnotationAttributes(DUBBO_TRANSPORTED_CLASS_NAME) : Collections.emptyMap();
}
return annotated;
return attributes;
}
@ -111,8 +123,12 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClass
* Adapt the instance of {@link DubboAdapterLoadBalancerInterceptor} to the {@link LoadBalancerInterceptor} Bean.
*
* @param restTemplate {@link LoadBalanced @LoadBalanced} {@link RestTemplate} Bean
* @param dubboTranslatedAttributes the annotation dubboTranslatedAttributes {@link RestTemplate} bean being annotated
* {@link DubboTransported @DubboTransported}
*/
private void adaptRestTemplate(RestTemplate restTemplate) {
private void adaptRestTemplate(RestTemplate restTemplate, Map<String, Object> dubboTranslatedAttributes) {
DubboTransportedMetadata dubboTransportedMetadata = buildDubboTransportedMetadata(dubboTranslatedAttributes);
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>(restTemplate.getInterceptors());
@ -120,12 +136,23 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClass
if (index > -1) {
interceptors.set(index, new DubboAdapterLoadBalancerInterceptor(repository, loadBalancerInterceptor,
restTemplate.getMessageConverters(),classLoader));
restTemplate.getMessageConverters(), classLoader,
dubboTransportedMetadata, dubboGenericServiceFactory));
}
restTemplate.setInterceptors(interceptors);
}
private DubboTransportedMetadata buildDubboTransportedMetadata(Map<String, Object> dubboTranslatedAttributes) {
DubboTransportedMetadata dubboTransportedMetadata = new DubboTransportedMetadata();
String protocol = (String) dubboTranslatedAttributes.get("protocol");
String cluster = (String) dubboTranslatedAttributes.get("cluster");
// resolve placeholders
dubboTransportedMetadata.setProtocol(environment.resolvePlaceholders(protocol));
dubboTransportedMetadata.setCluster(environment.resolvePlaceholders(cluster));
return dubboTransportedMetadata;
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;

View File

@ -26,6 +26,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository;
import org.springframework.cloud.alibaba.dubbo.metadata.resolver.DubboServiceBeanMetadataResolver;
import org.springframework.cloud.alibaba.dubbo.metadata.resolver.MetadataResolver;
import org.springframework.cloud.alibaba.dubbo.metadata.service.DubboGenericServiceFactory;
import org.springframework.cloud.alibaba.dubbo.openfeign.TargeterBeanPostProcessor;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.context.annotation.Bean;
@ -54,8 +55,9 @@ public class DubboOpenFeignAutoConfiguration {
@Bean
public TargeterBeanPostProcessor targeterBeanPostProcessor(Environment environment,
DubboServiceMetadataRepository dubboServiceMetadataRepository) {
return new TargeterBeanPostProcessor(environment, dubboServiceMetadataRepository);
DubboServiceMetadataRepository dubboServiceMetadataRepository,
DubboGenericServiceFactory dubboGenericServiceFactory) {
return new TargeterBeanPostProcessor(environment, dubboServiceMetadataRepository,dubboGenericServiceFactory);
}
}

View File

@ -0,0 +1,38 @@
/*
* 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 org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.alibaba.dubbo.metadata.service.DubboGenericServiceFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Spring Boot Auto-Configuration class for Dubbo Service
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
@Configuration
public class DubboServiceAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public DubboGenericServiceFactory dubboGenericServiceFactory() {
return new DubboGenericServiceFactory();
}
}

View File

@ -16,15 +16,17 @@
*/
package org.springframework.cloud.alibaba.dubbo.client.loadbalancer;
import com.alibaba.dubbo.config.spring.ReferenceBean;
import com.alibaba.dubbo.rpc.service.GenericException;
import com.alibaba.dubbo.rpc.service.GenericService;
import org.springframework.cloud.alibaba.dubbo.metadata.DubboServiceMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.DubboTransportedMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.MethodMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.RequestMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository;
import org.springframework.cloud.alibaba.dubbo.metadata.resolver.ParameterResolver;
import org.springframework.cloud.alibaba.dubbo.metadata.service.DubboGenericServiceFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
@ -52,18 +54,23 @@ public class DubboAdapterLoadBalancerInterceptor implements ClientHttpRequestInt
private final LoadBalancerInterceptor loadBalancerInterceptor;
private final List<HttpMessageConverter<?>> messageConverters;
private final DubboClientHttpResponseFactory clientHttpResponseFactory;
private final DubboTransportedMetadata dubboTransportedMetadata;
private final DubboGenericServiceFactory dubboGenericServiceFactory;
public DubboAdapterLoadBalancerInterceptor(DubboServiceMetadataRepository dubboServiceMetadataRepository,
LoadBalancerInterceptor loadBalancerInterceptor,
List<HttpMessageConverter<?>> messageConverters,
ClassLoader classLoader) {
ClassLoader classLoader,
DubboTransportedMetadata dubboTransportedMetadata,
DubboGenericServiceFactory dubboGenericServiceFactory) {
this.repository = dubboServiceMetadataRepository;
this.loadBalancerInterceptor = loadBalancerInterceptor;
this.messageConverters = messageConverters;
this.dubboTransportedMetadata = dubboTransportedMetadata;
this.clientHttpResponseFactory = new DubboClientHttpResponseFactory(messageConverters, classLoader);
this.dubboGenericServiceFactory = dubboGenericServiceFactory;
}
@Override
@ -79,19 +86,21 @@ public class DubboAdapterLoadBalancerInterceptor implements ClientHttpRequestInt
RequestMetadata clientMetadata = buildRequestMetadata(request, uriComponents);
RestMethodMetadata restMethodMetadata = repository.getRestMethodMetadata(serviceName, clientMetadata);
DubboServiceMetadata dubboServiceMetadata = repository.get(serviceName, clientMetadata);
ReferenceBean<GenericService> referenceBean = repository.getReferenceBean(serviceName, clientMetadata);
if (referenceBean == null || restMethodMetadata == null) {
if (dubboServiceMetadata == null) { // if DubboServiceMetadata is not found
return loadBalancerInterceptor.intercept(request, body, execution);
}
RestMethodMetadata restMethodMetadata = dubboServiceMetadata.getRestMethodMetadata();
GenericService genericService = dubboGenericServiceFactory.create(dubboServiceMetadata, dubboTransportedMetadata);
Object result = null;
GenericException exception = null;
try {
result = invokeService(restMethodMetadata, referenceBean, clientMetadata);
result = invokeService(restMethodMetadata, genericService, clientMetadata);
} catch (GenericException e) {
exception = e;
}
@ -99,7 +108,7 @@ public class DubboAdapterLoadBalancerInterceptor implements ClientHttpRequestInt
return clientHttpResponseFactory.build(result, exception, clientMetadata, restMethodMetadata);
}
private Object invokeService(RestMethodMetadata restMethodMetadata, ReferenceBean<GenericService> referenceBean,
private Object invokeService(RestMethodMetadata restMethodMetadata, GenericService genericService,
RequestMetadata clientMetadata) throws GenericException {
MethodMetadata methodMetadata = restMethodMetadata.getMethod();
@ -110,8 +119,6 @@ public class DubboAdapterLoadBalancerInterceptor implements ClientHttpRequestInt
Object[] parameters = parameterResolver.resolveParameters(restMethodMetadata, clientMetadata);
GenericService genericService = referenceBean.get();
Object result = genericService.$invoke(methodName, parameterTypes, parameters);
return result;

View File

@ -0,0 +1,58 @@
/*
* 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.metadata;
import java.util.Objects;
/**
* Dubbo Service Metadata
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
public class DubboServiceMetadata {
private final ServiceRestMetadata serviceRestMetadata;
private final RestMethodMetadata restMethodMetadata;
public DubboServiceMetadata(ServiceRestMetadata serviceRestMetadata, RestMethodMetadata restMethodMetadata) {
this.serviceRestMetadata = serviceRestMetadata;
this.restMethodMetadata = restMethodMetadata;
}
public ServiceRestMetadata getServiceRestMetadata() {
return serviceRestMetadata;
}
public RestMethodMetadata getRestMethodMetadata() {
return restMethodMetadata;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof DubboServiceMetadata)) return false;
DubboServiceMetadata that = (DubboServiceMetadata) o;
return Objects.equals(serviceRestMetadata, that.serviceRestMetadata) &&
Objects.equals(restMethodMetadata, that.restMethodMetadata);
}
@Override
public int hashCode() {
return Objects.hash(serviceRestMetadata, restMethodMetadata);
}
}

View File

@ -0,0 +1,61 @@
/*
* 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.metadata;
import org.springframework.cloud.alibaba.dubbo.annotation.DubboTransported;
import java.util.Objects;
/**
* {@link DubboTransported @DubboTransported} Metadata
*/
public class DubboTransportedMetadata {
private String protocol;
private String cluster;
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public String getCluster() {
return cluster;
}
public void setCluster(String cluster) {
this.cluster = cluster;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof DubboTransportedMetadata)) return false;
DubboTransportedMetadata that = (DubboTransportedMetadata) o;
return Objects.equals(protocol, that.protocol) &&
Objects.equals(cluster, that.cluster);
}
@Override
public int hashCode() {
return Objects.hash(protocol, cluster);
}
}

View File

@ -19,55 +19,88 @@ package org.springframework.cloud.alibaba.dubbo.metadata;
import org.springframework.cloud.alibaba.dubbo.annotation.DubboTransported;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;
/**
* {@link MethodMetadata} annotated {@link DubboTransported @DubboTransported}
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
public class DubboTransportedMethodMetadata extends MethodMetadata {
public class DubboTransportedMethodMetadata {
private String protocol;
private final DubboTransportedMetadata dubboTransportedMetadata;
private String cluster;
private final MethodMetadata methodMetadata;
public DubboTransportedMethodMetadata(Method method) {
super(method);
this.methodMetadata = new MethodMetadata(method);
this.dubboTransportedMetadata = new DubboTransportedMetadata();
}
public String getProtocol() {
return protocol;
return dubboTransportedMetadata.getProtocol();
}
public void setProtocol(String protocol) {
this.protocol = protocol;
dubboTransportedMetadata.setProtocol(protocol);
}
public String getCluster() {
return cluster;
return dubboTransportedMetadata.getCluster();
}
public void setCluster(String cluster) {
this.cluster = cluster;
dubboTransportedMetadata.setCluster(cluster);
}
public String getName() {
return methodMetadata.getName();
}
public void setName(String name) {
methodMetadata.setName(name);
}
public String getReturnType() {
return methodMetadata.getReturnType();
}
public void setReturnType(String returnType) {
methodMetadata.setReturnType(returnType);
}
public List<MethodParameterMetadata> getParams() {
return methodMetadata.getParams();
}
public void setParams(List<MethodParameterMetadata> params) {
methodMetadata.setParams(params);
}
public Method getMethod() {
return methodMetadata.getMethod();
}
public DubboTransportedMetadata getDubboTransportedMetadata() {
return dubboTransportedMetadata;
}
public MethodMetadata getMethodMetadata() {
return methodMetadata;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof DubboTransportedMethodMetadata)) return false;
if (!super.equals(o)) return false;
DubboTransportedMethodMetadata that = (DubboTransportedMethodMetadata) o;
if (protocol != null ? !protocol.equals(that.protocol) : that.protocol != null) return false;
return cluster != null ? cluster.equals(that.cluster) : that.cluster == null;
return Objects.equals(dubboTransportedMetadata, that.dubboTransportedMetadata) &&
Objects.equals(methodMetadata, that.methodMetadata);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (protocol != null ? protocol.hashCode() : 0);
result = 31 * result + (cluster != null ? cluster.hashCode() : 0);
return result;
return Objects.hash(dubboTransportedMetadata, methodMetadata);
}
}

View File

@ -20,13 +20,14 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* Method Request Metadata
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class RestMethodMetadata {

View File

@ -16,15 +16,12 @@
*/
package org.springframework.cloud.alibaba.dubbo.metadata.repository;
import com.alibaba.dubbo.config.spring.ReferenceBean;
import com.alibaba.dubbo.rpc.service.GenericService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.alibaba.dubbo.http.matcher.RequestMetadataMatcher;
import org.springframework.cloud.alibaba.dubbo.metadata.DubboServiceMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.RequestMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.service.MetadataConfigService;
import org.springframework.http.HttpRequest;
@ -35,10 +32,6 @@ import java.util.Map;
import java.util.Set;
import static org.springframework.cloud.alibaba.dubbo.http.DefaultHttpRequest.builder;
import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceGroup;
import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceInterface;
import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceSegments;
import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceVersion;
import static org.springframework.util.CollectionUtils.isEmpty;
/**
@ -53,15 +46,9 @@ public class DubboServiceMetadataRepository {
/**
* Key is application name
* Value is Map<RequestMetadata, ReferenceBean<GenericService>>
* Value is Map<RequestMetadata, DubboServiceMetadata>
*/
private Map<String, Map<RequestMetadataMatcher, ReferenceBean<GenericService>>> referenceBeansRepository = newHashMap();
/**
* Key is application name
* Value is Map<RequestMetadata, RestMethodMetadata>
*/
private Map<String, Map<RequestMetadataMatcher, RestMethodMetadata>> restMethodMetadataRepository = newHashMap();
private Map<String, Map<RequestMetadataMatcher, DubboServiceMetadata>> repository = newHashMap();
@Autowired
private MetadataConfigService metadataConfigService;
@ -73,7 +60,7 @@ public class DubboServiceMetadataRepository {
*/
public void initialize(String serviceName) {
if (referenceBeansRepository.containsKey(serviceName)) {
if (repository.containsKey(serviceName)) {
return;
}
@ -87,29 +74,28 @@ public class DubboServiceMetadataRepository {
return;
}
Map<RequestMetadataMatcher, ReferenceBean<GenericService>> genericServicesMap = getReferenceBeansMap(serviceName);
Map<RequestMetadataMatcher, RestMethodMetadata> restMethodMetadataMap = getRestMethodMetadataMap(serviceName);
Map<RequestMetadataMatcher, DubboServiceMetadata> metadataMap = getMetadataMap(serviceName);
for (ServiceRestMetadata serviceRestMetadata : serviceRestMetadataSet) {
ReferenceBean<GenericService> referenceBean = adaptReferenceBean(serviceRestMetadata);
serviceRestMetadata.getMeta().forEach(restMethodMetadata -> {
RequestMetadata requestMetadata = restMethodMetadata.getRequest();
RequestMetadataMatcher matcher = new RequestMetadataMatcher(requestMetadata);
genericServicesMap.put(matcher, referenceBean);
restMethodMetadataMap.put(matcher, restMethodMetadata);
DubboServiceMetadata metadata = new DubboServiceMetadata(serviceRestMetadata, restMethodMetadata);
metadataMap.put(matcher, metadata);
});
}
}
public ReferenceBean<GenericService> getReferenceBean(String serviceName, RequestMetadata requestMetadata) {
return match(referenceBeansRepository, serviceName, requestMetadata);
}
public RestMethodMetadata getRestMethodMetadata(String serviceName, RequestMetadata requestMetadata) {
return match(restMethodMetadataRepository, serviceName, requestMetadata);
/**
* Get a {@link DubboServiceMetadata} by the specified service name if {@link RequestMetadata} matched
*
* @param serviceName service name
* @param requestMetadata {@link RequestMetadata} to be matched
* @return {@link DubboServiceMetadata} if matched, or <code>null</code>
*/
public DubboServiceMetadata get(String serviceName, RequestMetadata requestMetadata) {
return match(repository, serviceName, requestMetadata);
}
private static <T> T match(Map<String, Map<RequestMetadataMatcher, T>> repository, String serviceName,
@ -140,28 +126,8 @@ public class DubboServiceMetadataRepository {
return object;
}
private ReferenceBean<GenericService> adaptReferenceBean(ServiceRestMetadata serviceRestMetadata) {
String dubboServiceName = serviceRestMetadata.getName();
String[] segments = getServiceSegments(dubboServiceName);
String interfaceName = getServiceInterface(segments);
String version = getServiceVersion(segments);
String group = getServiceGroup(segments);
ReferenceBean<GenericService> referenceBean = new ReferenceBean<GenericService>();
referenceBean.setGeneric(true);
referenceBean.setInterface(interfaceName);
referenceBean.setVersion(version);
referenceBean.setGroup(group);
return referenceBean;
}
private Map<RequestMetadataMatcher, ReferenceBean<GenericService>> getReferenceBeansMap(String serviceName) {
return getMap(referenceBeansRepository, serviceName);
}
private Map<RequestMetadataMatcher, RestMethodMetadata> getRestMethodMetadataMap(String serviceName) {
return getMap(restMethodMetadataRepository, serviceName);
private Map<RequestMetadataMatcher, DubboServiceMetadata> getMetadataMap(String serviceName) {
return getMap(repository, serviceName);
}
private static <K, V> Map<K, V> getMap(Map<String, Map<K, V>> repository, String key) {

View File

@ -0,0 +1,79 @@
/*
* 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.metadata.service;
import com.alibaba.dubbo.config.spring.ReferenceBean;
import com.alibaba.dubbo.rpc.service.GenericService;
import org.springframework.cloud.alibaba.dubbo.metadata.DubboServiceMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.DubboTransportedMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceGroup;
import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceInterface;
import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceSegments;
import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceVersion;
/**
* Dubbo {@link GenericService} Factory
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
public class DubboGenericServiceFactory {
private final ConcurrentMap<Integer, GenericService> cache = new ConcurrentHashMap<>();
public GenericService create(DubboServiceMetadata dubboServiceMetadata,
DubboTransportedMetadata dubboTransportedMetadata) {
Integer key = Objects.hash(dubboServiceMetadata, dubboTransportedMetadata);
GenericService genericService = cache.get(key);
if (genericService == null) {
genericService = build(dubboServiceMetadata.getServiceRestMetadata(), dubboTransportedMetadata);
cache.putIfAbsent(key, genericService);
}
return genericService;
}
private GenericService build(ServiceRestMetadata serviceRestMetadata,
DubboTransportedMetadata dubboTransportedMetadata) {
String dubboServiceName = serviceRestMetadata.getName();
String[] segments = getServiceSegments(dubboServiceName);
String interfaceName = getServiceInterface(segments);
String version = getServiceVersion(segments);
String group = getServiceGroup(segments);
ReferenceBean<GenericService> referenceBean = new ReferenceBean<GenericService>();
referenceBean.setGeneric(true);
referenceBean.setInterface(interfaceName);
referenceBean.setVersion(version);
referenceBean.setGroup(group);
referenceBean.setProtocol(dubboTransportedMetadata.getProtocol());
referenceBean.setCluster(dubboTransportedMetadata.getCluster());
return referenceBean.get();
}
}

View File

@ -20,6 +20,7 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository;
import org.springframework.cloud.alibaba.dubbo.metadata.service.DubboGenericServiceFactory;
import org.springframework.core.env.Environment;
import static java.lang.reflect.Proxy.newProxyInstance;
@ -39,12 +40,16 @@ public class TargeterBeanPostProcessor implements BeanPostProcessor, BeanClassLo
private final DubboServiceMetadataRepository dubboServiceMetadataRepository;
private final DubboGenericServiceFactory dubboGenericServiceFactory;
private ClassLoader classLoader;
public TargeterBeanPostProcessor(Environment environment,
DubboServiceMetadataRepository dubboServiceMetadataRepository) {
DubboServiceMetadataRepository dubboServiceMetadataRepository,
DubboGenericServiceFactory dubboGenericServiceFactory) {
this.environment = environment;
this.dubboServiceMetadataRepository = dubboServiceMetadataRepository;
this.dubboGenericServiceFactory = dubboGenericServiceFactory;
}
@Override
@ -58,7 +63,8 @@ public class TargeterBeanPostProcessor implements BeanPostProcessor, BeanClassLo
Class<?> targetClass = resolveClassName(TARGETER_CLASS_NAME, classLoader);
if (targetClass.isAssignableFrom(beanClass)) {
return newProxyInstance(classLoader, new Class[]{targetClass},
new TargeterInvocationHandler(bean, environment, dubboServiceMetadataRepository));
new TargeterInvocationHandler(bean, environment, dubboServiceMetadataRepository,
dubboGenericServiceFactory));
}
return bean;
}

View File

@ -17,16 +17,18 @@
package org.springframework.cloud.alibaba.dubbo.openfeign;
import com.alibaba.dubbo.config.spring.ReferenceBean;
import com.alibaba.dubbo.rpc.service.GenericService;
import feign.Contract;
import feign.Target;
import org.springframework.cloud.alibaba.dubbo.metadata.DubboServiceMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.DubboTransportedMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.DubboTransportedMethodMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.RequestMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository;
import org.springframework.cloud.alibaba.dubbo.metadata.resolver.DubboTransportedMethodMetadataResolver;
import org.springframework.cloud.alibaba.dubbo.metadata.service.DubboGenericServiceFactory;
import org.springframework.cloud.openfeign.FeignContext;
import org.springframework.core.env.Environment;
@ -51,11 +53,14 @@ class TargeterInvocationHandler implements InvocationHandler {
private final DubboServiceMetadataRepository repository;
TargeterInvocationHandler(Object bean, Environment environment,
DubboServiceMetadataRepository repository) {
private final DubboGenericServiceFactory dubboGenericServiceFactory;
TargeterInvocationHandler(Object bean, Environment environment, DubboServiceMetadataRepository repository,
DubboGenericServiceFactory dubboGenericServiceFactory) {
this.bean = bean;
this.environment = environment;
this.repository = repository;
this.dubboGenericServiceFactory = dubboGenericServiceFactory;
}
@Override
@ -115,12 +120,12 @@ class TargeterInvocationHandler implements InvocationHandler {
Map<Method, GenericService> genericServicesMap = new HashMap<>();
methodRequestMetadataMap.forEach((dubboTransportedMethodMetadata, requestMetadata) -> {
ReferenceBean<GenericService> referenceBean = repository.getReferenceBean(serviceName, requestMetadata);
RestMethodMetadata restMethodMetadata = repository.getRestMethodMetadata(serviceName, requestMetadata);
DubboServiceMetadata dubboServiceMetadata = repository.get(serviceName, requestMetadata);
RestMethodMetadata restMethodMetadata = dubboServiceMetadata.getRestMethodMetadata();
org.springframework.cloud.alibaba.dubbo.metadata.MethodMetadata methodMetadata = restMethodMetadata.getMethod();
referenceBean.setProtocol(dubboTransportedMethodMetadata.getProtocol());
referenceBean.setCluster(dubboTransportedMethodMetadata.getCluster());
genericServicesMap.put(dubboTransportedMethodMetadata.getMethod(), referenceBean.get());
DubboTransportedMetadata dubboTransportedMetadata = dubboTransportedMethodMetadata.getDubboTransportedMetadata();
GenericService genericService = dubboGenericServiceFactory.create(dubboServiceMetadata, dubboTransportedMetadata);
genericServicesMap.put(dubboTransportedMethodMetadata.getMethod(), genericService);
methodMetadataMap.put(dubboTransportedMethodMetadata.getMethod(), methodMetadata);
});

View File

@ -2,7 +2,8 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboMetadataAutoConfiguration,\
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboOpenFeignAutoConfiguration,\
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboRestMetadataRegistrationAutoConfiguration,\
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboLoadBalancedRestTemplateAutoConfiguration
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboLoadBalancedRestTemplateAutoConfiguration,\
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceAutoConfiguration
org.springframework.context.ApplicationContextInitializer=\
org.springframework.cloud.alibaba.dubbo.context.DubboServiceRegistrationApplicationContextInitializer