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:
parent
f34e1883e3
commit
5c2b118523
@ -58,7 +58,7 @@ public class DubboOpenFeignAutoConfiguration {
|
||||
private ObjectProvider<FeignContext> feignContextObjectProvider;
|
||||
|
||||
@EventListener(ApplicationReadyEvent.class)
|
||||
public void onContextRefreshed(ApplicationReadyEvent event) {
|
||||
public void onApplicationReady(ApplicationReadyEvent event) {
|
||||
ConfigurableApplicationContext applicationContext = event.getApplicationContext();
|
||||
// Resolve the subscribed service names for @FeignClient
|
||||
Set<String> feignClientServiceNames = resolveFeignClientServiceNames(applicationContext);
|
||||
|
@ -17,10 +17,11 @@
|
||||
package org.springframework.cloud.alibaba.dubbo.autoconfigure;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import feign.Contract;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.cloud.alibaba.dubbo.rest.feign.FeignRestMetadataResolver;
|
||||
import org.springframework.cloud.alibaba.dubbo.rest.feign.RestMetadataConfigService;
|
||||
import org.springframework.cloud.alibaba.dubbo.rest.feign.RestMetadataResolver;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
@ -35,14 +36,9 @@ import org.springframework.core.Ordered;
|
||||
public class DubboRestAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ObjectMapper objectMapper() {
|
||||
return new ObjectMapper();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RestMetadataResolver metadataJsonResolver(ObjectMapper objectMapper) {
|
||||
return new RestMetadataResolver(objectMapper);
|
||||
public FeignRestMetadataResolver metadataJsonResolver(
|
||||
ObjectProvider<ObjectMapper> objectMapper, ObjectProvider<Contract> contract) {
|
||||
return new FeignRestMetadataResolver(objectMapper, contract);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
@ -31,7 +31,7 @@ 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.feign.FeignRestMetadataResolver;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -63,7 +63,7 @@ public class DubboRestDiscoveryAutoConfiguration {
|
||||
private DiscoveryClient discoveryClient;
|
||||
|
||||
@Autowired
|
||||
private RestMetadataResolver restMetadataResolver;
|
||||
private FeignRestMetadataResolver feignRestMetadataResolver;
|
||||
|
||||
@Autowired(required = false)
|
||||
private ObjectMapper objectMapper = new ObjectMapper();
|
||||
@ -206,7 +206,7 @@ public class DubboRestDiscoveryAutoConfiguration {
|
||||
// Map<String, List<String>> restMetadata = objectMapper.readValue(restMetadataJson, Map.class);
|
||||
//
|
||||
// restMetadata.forEach((dubboServiceName, restJsons) -> {
|
||||
// restJsons.stream().map(restMetadataResolver::resolveRequest).forEach(request -> {
|
||||
// restJsons.stream().map(feignRestMetadataResolver::resolveRequest).forEach(request -> {
|
||||
// referenceBeanCache.put(request.toString(), buildReferenceBean(dubboServiceName));
|
||||
// });
|
||||
// });
|
||||
@ -231,7 +231,7 @@ public class DubboRestDiscoveryAutoConfiguration {
|
||||
// Map<String, List<String>> restMetadata = objectMapper.readValue(restMetadataJson, Map.class);
|
||||
//
|
||||
// restMetadata.forEach((dubboServiceName, restJsons) -> {
|
||||
// restJsons.stream().map(restMetadataResolver::resolveRequest).forEach(request -> {
|
||||
// restJsons.stream().map(feignRestMetadataResolver::resolveRequest).forEach(request -> {
|
||||
// referenceBeanCache.put(request.toString(), buildReferenceBean(dubboServiceName));
|
||||
// });
|
||||
// });
|
||||
|
@ -23,8 +23,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
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.FeignRestMetadataResolver;
|
||||
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.client.discovery.event.InstancePreRegisteredEvent;
|
||||
import org.springframework.cloud.client.serviceregistry.Registration;
|
||||
@ -57,7 +57,7 @@ public class DubboRestMetadataRegistrationAutoConfiguration {
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Autowired
|
||||
private RestMetadataResolver restMetadataResolver;
|
||||
private FeignRestMetadataResolver feignRestMetadataResolver;
|
||||
|
||||
@Autowired
|
||||
private RestMetadataConfigService metadataConfigService;
|
||||
@ -66,7 +66,7 @@ public class DubboRestMetadataRegistrationAutoConfiguration {
|
||||
@EventListener(ServiceBeanExportedEvent.class)
|
||||
public void recordRestMetadata(ServiceBeanExportedEvent event) throws JsonProcessingException {
|
||||
ServiceBean serviceBean = event.getServiceBean();
|
||||
serviceRestMetadata.addAll(restMetadataResolver.resolve(serviceBean));
|
||||
serviceRestMetadata.addAll(feignRestMetadataResolver.resolveServiceRestMetadata(serviceBean));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,10 @@
|
||||
*/
|
||||
package org.springframework.cloud.alibaba.dubbo.openfeign;
|
||||
|
||||
import feign.Feign;
|
||||
import feign.*;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.codec.ErrorDecoder;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboOpenFeignAutoConfiguration;
|
||||
@ -45,12 +48,132 @@ public class DubboFeignClientsConfiguration {
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (bean instanceof Feign.Builder) {
|
||||
Feign.Builder builder = (Feign.Builder) bean;
|
||||
Feign feign = builder.build();
|
||||
BuilderWrapper wrapper = new BuilderWrapper(builder);
|
||||
return wrapper;
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static class BuilderWrapper extends Feign.Builder {
|
||||
|
||||
private final Feign.Builder delegate;
|
||||
|
||||
private BuilderWrapper(Feign.Builder delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign.Builder logLevel(Logger.Level logLevel) {
|
||||
return delegate.logLevel(logLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign.Builder contract(Contract contract) {
|
||||
delegate.contract(contract);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign.Builder client(Client client) {
|
||||
delegate.client(client);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign.Builder retryer(Retryer retryer) {
|
||||
delegate.retryer(retryer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign.Builder logger(Logger logger) {
|
||||
delegate.logger(logger);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign.Builder encoder(Encoder encoder) {
|
||||
delegate.encoder(encoder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign.Builder decoder(Decoder decoder) {
|
||||
delegate.decoder(decoder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign.Builder queryMapEncoder(QueryMapEncoder queryMapEncoder) {
|
||||
delegate.queryMapEncoder(queryMapEncoder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign.Builder mapAndDecode(ResponseMapper mapper, Decoder decoder) {
|
||||
delegate.mapAndDecode(mapper, decoder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign.Builder decode404() {
|
||||
delegate.decode404();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign.Builder errorDecoder(ErrorDecoder errorDecoder) {
|
||||
delegate.errorDecoder(errorDecoder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign.Builder options(Request.Options options) {
|
||||
delegate.options(options);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign.Builder requestInterceptor(RequestInterceptor requestInterceptor) {
|
||||
delegate.requestInterceptor(requestInterceptor);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign.Builder requestInterceptors(Iterable<RequestInterceptor> requestInterceptors) {
|
||||
delegate.requestInterceptors(requestInterceptors);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign.Builder invocationHandlerFactory(InvocationHandlerFactory invocationHandlerFactory) {
|
||||
delegate.invocationHandlerFactory(invocationHandlerFactory);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign.Builder doNotCloseAfterDecode() {
|
||||
delegate.doNotCloseAfterDecode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T target(Class<T> apiType, String url) {
|
||||
return delegate.target(apiType, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T target(Target<T> target) {
|
||||
return delegate.target(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feign build() {
|
||||
return delegate.build();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -26,10 +26,12 @@ import feign.Request;
|
||||
import feign.RequestTemplate;
|
||||
import feign.jaxrs2.JAXRS2Contract;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry;
|
||||
import org.springframework.cloud.alibaba.dubbo.rest.metadata.MethodRestMetadata;
|
||||
import org.springframework.cloud.alibaba.dubbo.rest.metadata.ServiceRestMetadata;
|
||||
@ -44,18 +46,29 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* The JSON resolver for {@link MethodMetadata}
|
||||
* The REST metadata resolver for Feign
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
public class RestMetadataResolver implements BeanClassLoaderAware, SmartInitializingSingleton {
|
||||
public class FeignRestMetadataResolver implements BeanClassLoaderAware, SmartInitializingSingleton {
|
||||
|
||||
private static final String METHOD_PROPERTY_NAME = "method";
|
||||
private static final String URL_PROPERTY_NAME = "url";
|
||||
private static final String HEADERS_PROPERTY_NAME = "headers";
|
||||
|
||||
private static final String[] CONTRACT_CLASS_NAMES = {
|
||||
"feign.jaxrs2.JAXRS2Contract",
|
||||
"org.springframework.cloud.openfeign.support.SpringMvcContract",
|
||||
};
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
private final ObjectProvider<Contract> contract;
|
||||
|
||||
/**
|
||||
* Feign Contracts
|
||||
*/
|
||||
@ -63,37 +76,44 @@ public class RestMetadataResolver implements BeanClassLoaderAware, SmartInitiali
|
||||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
@Autowired
|
||||
private ObjectProvider<Contract> contractObjectProvider;
|
||||
@Value("${spring.application.name}")
|
||||
private String currentApplicationName;
|
||||
|
||||
public RestMetadataResolver(ObjectMapper objectMapper) {
|
||||
this.objectMapper = objectMapper;
|
||||
public FeignRestMetadataResolver(ObjectProvider<ObjectMapper> objectMapper, ObjectProvider<Contract> contract) {
|
||||
this.objectMapper = objectMapper.getIfAvailable();
|
||||
this.contract = contract;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterSingletonsInstantiated() {
|
||||
|
||||
Collection<Contract> contracts = new LinkedList<>();
|
||||
LinkedList<Contract> contracts = new LinkedList<>();
|
||||
|
||||
// Add injected Contract , for example SpringMvcContract Bean under Spring Cloud Open Feign
|
||||
Contract contract = contractObjectProvider.getIfAvailable();
|
||||
if (contract != null) {
|
||||
contracts.add(contract);
|
||||
} else {
|
||||
if (ClassUtils.isPresent("org.springframework.cloud.openfeign.support.SpringMvcContract", classLoader)) {
|
||||
contracts.add(new SpringMvcContract());
|
||||
}
|
||||
}
|
||||
// Add injected Contract if available, for example SpringMvcContract Bean under Spring Cloud Open Feign
|
||||
contract.ifAvailable(contracts::add);
|
||||
|
||||
// Add JAXRS2Contract if it's present in Class Path
|
||||
if (ClassUtils.isPresent("javax.ws.rs.Path", classLoader)) {
|
||||
contracts.add(new JAXRS2Contract());
|
||||
}
|
||||
Stream.of(CONTRACT_CLASS_NAMES)
|
||||
.filter(this::isClassPresent) // filter the existed classes
|
||||
.map(this::loadContractClass) // load Contract Class
|
||||
.map(this::createContract) // create instance by the specified class
|
||||
.forEach(contracts::add); // add the Contract instance into contracts
|
||||
|
||||
this.contracts = Collections.unmodifiableCollection(contracts);
|
||||
}
|
||||
|
||||
public Set<ServiceRestMetadata> resolve(ServiceBean serviceBean) {
|
||||
private Contract createContract(Class<?> contractClassName) {
|
||||
return (Contract) BeanUtils.instantiateClass(contractClassName);
|
||||
}
|
||||
|
||||
private Class<?> loadContractClass(String contractClassName) {
|
||||
return ClassUtils.resolveClassName(contractClassName, classLoader);
|
||||
}
|
||||
|
||||
private boolean isClassPresent(String className) {
|
||||
return ClassUtils.isPresent(className, classLoader);
|
||||
}
|
||||
|
||||
public Set<ServiceRestMetadata> resolveServiceRestMetadata(ServiceBean serviceBean) {
|
||||
|
||||
Object bean = serviceBean.getRef();
|
||||
|
||||
@ -103,14 +123,7 @@ public class RestMetadataResolver implements BeanClassLoaderAware, SmartInitiali
|
||||
|
||||
Set<ServiceRestMetadata> serviceRestMetadata = new LinkedHashSet<>();
|
||||
|
||||
Set<MethodRestMetadata> methodRestMetadata = new LinkedHashSet<>();
|
||||
|
||||
contracts.stream()
|
||||
.map(contract -> contract.parseAndValidatateMetadata(bean.getClass()))
|
||||
.flatMap(v -> v.stream())
|
||||
.forEach(methodMetadata -> {
|
||||
methodRestMetadata.add(resolveMethodRestMetadata(methodMetadata, beanType, interfaceClass));
|
||||
});
|
||||
Set<MethodRestMetadata> methodRestMetadata = resolveMethodRestMetadata(beanType, interfaceClass);
|
||||
|
||||
List<URL> urls = serviceBean.getExportedUrls();
|
||||
|
||||
@ -126,6 +139,18 @@ public class RestMetadataResolver implements BeanClassLoaderAware, SmartInitiali
|
||||
return serviceRestMetadata;
|
||||
}
|
||||
|
||||
public Set<MethodRestMetadata> resolveMethodRestMetadata(Class<?> targetClass) {
|
||||
return resolveMethodRestMetadata(targetClass, targetClass);
|
||||
}
|
||||
|
||||
protected Set<MethodRestMetadata> resolveMethodRestMetadata(Class<?> targetClass, Class revisedClass) {
|
||||
return contracts.stream()
|
||||
.map(contract -> contract.parseAndValidatateMetadata(targetClass))
|
||||
.flatMap(v -> v.stream())
|
||||
.map(methodMetadata -> resolveMethodRestMetadata(methodMetadata, targetClass, revisedClass))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private String toJson(Object object) {
|
||||
String jsonContent = null;
|
||||
try {
|
||||
@ -137,6 +162,9 @@ public class RestMetadataResolver implements BeanClassLoaderAware, SmartInitiali
|
||||
}
|
||||
|
||||
private String regenerateConfigKey(String configKey, Class<?> beanType, Class<?> interfaceClass) {
|
||||
if (beanType.equals(interfaceClass)) {
|
||||
return configKey;
|
||||
}
|
||||
return StringUtils.replace(configKey, beanType.getSimpleName(), interfaceClass.getSimpleName());
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
|
||||
/**
|
||||
* Rest Metadata Config Service
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
public class RestMetadataConfigService {
|
||||
|
||||
@ -45,7 +47,7 @@ public class RestMetadataConfigService {
|
||||
* TODO JavaDoc
|
||||
*/
|
||||
private static String getServiceRestMetadataDataId(String serviceName) {
|
||||
return serviceName + "-rest-metadata.json";
|
||||
return "metadata:rest:" + serviceName + ".json";
|
||||
}
|
||||
|
||||
public void publishServiceRestMetadata(String serviceName, String restMetadataJSON)
|
||||
|
@ -10,4 +10,7 @@ dubbo:
|
||||
port: 9090
|
||||
server: netty
|
||||
registry:
|
||||
address: spring-cloud://nacos
|
||||
address: spring-cloud://nacos
|
||||
|
||||
server:
|
||||
port: 8080
|
Loading…
x
Reference in New Issue
Block a user