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

polish #761 update pkg name & maven coordinate for Greenwich

This commit is contained in:
fangjian0423
2019-07-23 11:03:04 +08:00
parent 3998ea23f7
commit 883c66f251
599 changed files with 4993 additions and 4526 deletions

View File

@@ -0,0 +1,87 @@
/*
* 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 com.alibaba.cloud.dubbo.openfeign;
import org.apache.dubbo.rpc.service.GenericService;
import com.alibaba.cloud.dubbo.metadata.RestMethodMetadata;
import com.alibaba.cloud.dubbo.service.DubboGenericServiceExecutionContext;
import com.alibaba.cloud.dubbo.service.DubboGenericServiceExecutionContextFactory;
import org.springframework.util.ClassUtils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Map;
import static org.apache.dubbo.common.utils.PojoUtils.realize;
/**
* Dubbo {@link GenericService} for {@link InvocationHandler}
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
public class DubboInvocationHandler implements InvocationHandler {
private final Map<Method, FeignMethodMetadata> feignMethodMetadataMap;
private final InvocationHandler defaultInvocationHandler;
private final DubboGenericServiceExecutionContextFactory contextFactory;
private final ClassLoader classLoader;
public DubboInvocationHandler(Map<Method, FeignMethodMetadata> feignMethodMetadataMap,
InvocationHandler defaultInvocationHandler,
ClassLoader classLoader,
DubboGenericServiceExecutionContextFactory contextFactory) {
this.feignMethodMetadataMap = feignMethodMetadataMap;
this.defaultInvocationHandler = defaultInvocationHandler;
this.classLoader = classLoader;
this.contextFactory = contextFactory;
}
@Override
public Object invoke(Object proxy, Method feignMethod, Object[] args) throws Throwable {
FeignMethodMetadata feignMethodMetadata = feignMethodMetadataMap.get(feignMethod);
if (feignMethodMetadata == null) {
return defaultInvocationHandler.invoke(proxy, feignMethod, args);
}
GenericService dubboGenericService = feignMethodMetadata.getDubboGenericService();
RestMethodMetadata dubboRestMethodMetadata = feignMethodMetadata.getDubboRestMethodMetadata();
RestMethodMetadata feignRestMethodMetadata = feignMethodMetadata.getFeignMethodMetadata();
DubboGenericServiceExecutionContext context = contextFactory.create(dubboRestMethodMetadata, feignRestMethodMetadata, args);
String methodName = context.getMethodName();
String[] parameterTypes = context.getParameterTypes();
Object[] parameters = context.getParameters();
Object result = dubboGenericService.$invoke(methodName, parameterTypes, parameters);
Class<?> returnType = getReturnType(dubboRestMethodMetadata);
return realize(result, returnType);
}
private Class<?> getReturnType(RestMethodMetadata dubboRestMethodMetadata) {
String returnType = dubboRestMethodMetadata.getReturnType();
return ClassUtils.resolveClassName(returnType, 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 com.alibaba.cloud.dubbo.openfeign;
import org.apache.dubbo.rpc.service.GenericService;
import com.alibaba.cloud.dubbo.metadata.RestMethodMetadata;
import java.lang.reflect.Method;
/**
* Feign {@link Method} Metadata
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
class FeignMethodMetadata {
private final GenericService dubboGenericService;
private final RestMethodMetadata dubboRestMethodMetadata;
private final RestMethodMetadata feignMethodMetadata;
FeignMethodMetadata(GenericService dubboGenericService, RestMethodMetadata dubboRestMethodMetadata,
RestMethodMetadata feignMethodMetadata) {
this.dubboGenericService = dubboGenericService;
this.dubboRestMethodMetadata = dubboRestMethodMetadata;
this.feignMethodMetadata = feignMethodMetadata;
}
GenericService getDubboGenericService() {
return dubboGenericService;
}
RestMethodMetadata getDubboRestMethodMetadata() {
return dubboRestMethodMetadata;
}
RestMethodMetadata getFeignMethodMetadata() {
return feignMethodMetadata;
}
}

View File

@@ -0,0 +1,85 @@
/*
* 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 com.alibaba.cloud.dubbo.openfeign;
import com.alibaba.cloud.dubbo.service.DubboGenericServiceExecutionContextFactory;
import com.alibaba.cloud.dubbo.service.DubboGenericServiceFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.config.BeanPostProcessor;
import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository;
import org.springframework.core.env.Environment;
import static java.lang.reflect.Proxy.newProxyInstance;
import static com.alibaba.cloud.dubbo.autoconfigure.DubboOpenFeignAutoConfiguration.TARGETER_CLASS_NAME;
import static org.springframework.util.ClassUtils.getUserClass;
import static org.springframework.util.ClassUtils.isPresent;
import static org.springframework.util.ClassUtils.resolveClassName;
/**
* org.springframework.cloud.openfeign.Targeter {@link BeanPostProcessor}
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
public class TargeterBeanPostProcessor implements BeanPostProcessor, BeanClassLoaderAware {
private final Environment environment;
private final DubboServiceMetadataRepository dubboServiceMetadataRepository;
private final DubboGenericServiceFactory dubboGenericServiceFactory;
private final DubboGenericServiceExecutionContextFactory contextFactory;
private ClassLoader classLoader;
public TargeterBeanPostProcessor(Environment environment,
DubboServiceMetadataRepository dubboServiceMetadataRepository,
DubboGenericServiceFactory dubboGenericServiceFactory,
DubboGenericServiceExecutionContextFactory contextFactory) {
this.environment = environment;
this.dubboServiceMetadataRepository = dubboServiceMetadataRepository;
this.dubboGenericServiceFactory = dubboGenericServiceFactory;
this.contextFactory = contextFactory;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
if (isPresent(TARGETER_CLASS_NAME, classLoader)) {
Class<?> beanClass = getUserClass(bean.getClass());
Class<?> targetClass = resolveClassName(TARGETER_CLASS_NAME, classLoader);
if (targetClass.isAssignableFrom(beanClass)) {
return newProxyInstance(classLoader, new Class[]{targetClass},
new TargeterInvocationHandler(bean, environment, classLoader, dubboServiceMetadataRepository,
dubboGenericServiceFactory, contextFactory));
}
}
return bean;
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
}

View File

@@ -0,0 +1,175 @@
/*
* 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 com.alibaba.cloud.dubbo.openfeign;
import org.apache.dubbo.rpc.service.GenericService;
import feign.Contract;
import feign.Target;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.cloud.dubbo.annotation.DubboTransported;
import com.alibaba.cloud.dubbo.metadata.DubboRestServiceMetadata;
import com.alibaba.cloud.dubbo.metadata.DubboTransportedMethodMetadata;
import com.alibaba.cloud.dubbo.metadata.MethodMetadata;
import com.alibaba.cloud.dubbo.metadata.RequestMetadata;
import com.alibaba.cloud.dubbo.metadata.RestMethodMetadata;
import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository;
import com.alibaba.cloud.dubbo.metadata.resolver.DubboTransportedMethodMetadataResolver;
import com.alibaba.cloud.dubbo.service.DubboGenericServiceExecutionContextFactory;
import com.alibaba.cloud.dubbo.service.DubboGenericServiceFactory;
import org.springframework.cloud.openfeign.FeignContext;
import org.springframework.core.env.Environment;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
import static java.lang.reflect.Proxy.newProxyInstance;
/**
* org.springframework.cloud.openfeign.Targeter {@link InvocationHandler}
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
class TargeterInvocationHandler implements InvocationHandler {
private final Logger logger = LoggerFactory.getLogger(getClass());
private final Object bean;
private final Environment environment;
private final ClassLoader classLoader;
private final DubboServiceMetadataRepository repository;
private final DubboGenericServiceFactory dubboGenericServiceFactory;
private final DubboGenericServiceExecutionContextFactory contextFactory;
TargeterInvocationHandler(Object bean, Environment environment,
ClassLoader classLoader,
DubboServiceMetadataRepository repository,
DubboGenericServiceFactory dubboGenericServiceFactory,
DubboGenericServiceExecutionContextFactory contextFactory) {
this.bean = bean;
this.environment = environment;
this.classLoader = classLoader;
this.repository = repository;
this.dubboGenericServiceFactory = dubboGenericServiceFactory;
this.contextFactory = contextFactory;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/**
* args[0]: FeignClientFactoryBean factory
* args[1]: Feign.Builder feign
* args[2]: FeignContext context
* args[3]: Target.HardCodedTarget<T> target
*/
FeignContext feignContext = cast(args[2]);
Target.HardCodedTarget<?> target = cast(args[3]);
// Execute Targeter#target method first
method.setAccessible(true);
// Get the default proxy object
Object defaultProxy = method.invoke(bean, args);
// Create Dubbo Proxy if required
return createDubboProxyIfRequired(feignContext, target, defaultProxy);
}
private Object createDubboProxyIfRequired(FeignContext feignContext, Target target, Object defaultProxy) {
DubboInvocationHandler dubboInvocationHandler = createDubboInvocationHandler(feignContext, target, defaultProxy);
if (dubboInvocationHandler == null) {
return defaultProxy;
}
return newProxyInstance(target.type().getClassLoader(), new Class<?>[]{target.type()}, dubboInvocationHandler);
}
private DubboInvocationHandler createDubboInvocationHandler(FeignContext feignContext, Target target,
Object defaultFeignClientProxy) {
// Service name equals @FeignClient.name()
String serviceName = target.name();
Class<?> targetType = target.type();
// Get Contract Bean from FeignContext
Contract contract = feignContext.getInstance(serviceName, Contract.class);
DubboTransportedMethodMetadataResolver resolver =
new DubboTransportedMethodMetadataResolver(environment, contract);
Map<DubboTransportedMethodMetadata, RestMethodMetadata> feignRestMethodMetadataMap = resolver.resolve(targetType);
if (feignRestMethodMetadataMap.isEmpty()) { // @DubboTransported method was not found from the Client interface
if (logger.isDebugEnabled()) {
logger.debug("@{} method was not found in the Feign target type[{}]",
DubboTransported.class.getSimpleName(), targetType.getName());
}
return null;
}
// Update Metadata
repository.initialize(serviceName);
Map<Method, FeignMethodMetadata> feignMethodMetadataMap = getFeignMethodMetadataMap(serviceName, feignRestMethodMetadataMap);
InvocationHandler defaultFeignClientInvocationHandler = Proxy.getInvocationHandler(defaultFeignClientProxy);
DubboInvocationHandler dubboInvocationHandler = new DubboInvocationHandler(feignMethodMetadataMap,
defaultFeignClientInvocationHandler, classLoader, contextFactory);
return dubboInvocationHandler;
}
private Map<Method, FeignMethodMetadata> getFeignMethodMetadataMap(String serviceName,
Map<DubboTransportedMethodMetadata, RestMethodMetadata>
feignRestMethodMetadataMap) {
Map<Method, FeignMethodMetadata> feignMethodMetadataMap = new HashMap<>();
for (Map.Entry<DubboTransportedMethodMetadata, RestMethodMetadata> entry : feignRestMethodMetadataMap.entrySet()) {
RestMethodMetadata feignRestMethodMetadata = entry.getValue();
RequestMetadata feignRequestMetadata = feignRestMethodMetadata.getRequest();
DubboRestServiceMetadata metadata = repository.get(serviceName, feignRequestMetadata);
if (metadata != null) {
DubboTransportedMethodMetadata dubboTransportedMethodMetadata = entry.getKey();
Map<String, Object> dubboTranslatedAttributes = dubboTransportedMethodMetadata.getAttributes();
Method method = dubboTransportedMethodMetadata.getMethod();
GenericService dubboGenericService = dubboGenericServiceFactory.create(metadata, dubboTranslatedAttributes);
RestMethodMetadata dubboRestMethodMetadata = metadata.getRestMethodMetadata();
MethodMetadata methodMetadata = dubboTransportedMethodMetadata.getMethodMetadata();
FeignMethodMetadata feignMethodMetadata = new FeignMethodMetadata(dubboGenericService,
dubboRestMethodMetadata, feignRestMethodMetadata);
feignMethodMetadataMap.put(method, feignMethodMetadata);
}
}
return feignMethodMetadataMap;
}
private static <T> T cast(Object object) {
return (T) object;
}
}