mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
fixes #9
This commit is contained in:
parent
0c8bd1b58a
commit
53643b94ce
@ -1,12 +1,13 @@
|
||||
package org.springframework.cloud.alibaba.cloud.examples;
|
||||
|
||||
import com.alibaba.csp.sentinel.datasource.Converter;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.alibaba.sentinel.annotation.SentinelProtect;
|
||||
import org.springframework.cloud.alibaba.sentinel.annotation.SentinelRestTemplate;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import com.alibaba.csp.sentinel.datasource.Converter;
|
||||
|
||||
/**
|
||||
* @author xiaojing
|
||||
*/
|
||||
@ -14,7 +15,7 @@ import org.springframework.web.client.RestTemplate;
|
||||
public class ServiceApplication {
|
||||
|
||||
@Bean
|
||||
@SentinelProtect(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
|
||||
@SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
@ -25,9 +26,9 @@ public class ServiceApplication {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Converter myConverter() {
|
||||
return new JsonFlowRuleListConverter();
|
||||
}
|
||||
public Converter myConverter() {
|
||||
return new JsonFlowRuleListConverter();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ServiceApplication.class, args);
|
||||
|
@ -16,7 +16,11 @@
|
||||
|
||||
package org.springframework.cloud.alibaba.sentinel.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author fangjian
|
||||
@ -24,7 +28,7 @@ import java.lang.annotation.*;
|
||||
@Target({ ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface SentinelProtect {
|
||||
public @interface SentinelRestTemplate {
|
||||
|
||||
String blockHandler() default "";
|
||||
|
@ -25,17 +25,17 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.cloud.alibaba.sentinel.annotation.SentinelProtect;
|
||||
import org.springframework.cloud.alibaba.sentinel.annotation.SentinelRestTemplate;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.type.StandardMethodMetadata;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* PostProcessor handle @SentinelProtect Annotation, add interceptor for RestTemplate
|
||||
* PostProcessor handle @SentinelRestTemplate Annotation, add interceptor for RestTemplate
|
||||
*
|
||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
* @see SentinelProtect
|
||||
* @see SentinelRestTemplate
|
||||
* @see SentinelProtectInterceptor
|
||||
*/
|
||||
public class SentinelBeanPostProcessor implements MergedBeanDefinitionPostProcessor {
|
||||
@ -43,16 +43,16 @@ public class SentinelBeanPostProcessor implements MergedBeanDefinitionPostProces
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private ConcurrentHashMap<String, SentinelProtect> cache = new ConcurrentHashMap<>();
|
||||
private ConcurrentHashMap<String, SentinelRestTemplate> cache = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
|
||||
Class<?> beanType, String beanName) {
|
||||
if (checkSentinelProtect(beanDefinition, beanType)) {
|
||||
SentinelProtect sentinelProtect = ((StandardMethodMetadata) beanDefinition
|
||||
SentinelRestTemplate sentinelRestTemplate = ((StandardMethodMetadata) beanDefinition
|
||||
.getSource()).getIntrospectedMethod()
|
||||
.getAnnotation(SentinelProtect.class);
|
||||
cache.put(beanName, sentinelProtect);
|
||||
.getAnnotation(SentinelRestTemplate.class);
|
||||
cache.put(beanName, sentinelRestTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,26 +61,26 @@ public class SentinelBeanPostProcessor implements MergedBeanDefinitionPostProces
|
||||
return beanType == RestTemplate.class
|
||||
&& beanDefinition.getSource() instanceof StandardMethodMetadata
|
||||
&& ((StandardMethodMetadata) beanDefinition.getSource())
|
||||
.isAnnotated(SentinelProtect.class.getName());
|
||||
.isAnnotated(SentinelRestTemplate.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
if (cache.containsKey(beanName)) {
|
||||
// add interceptor for each RestTemplate with @SentinelProtect annotation
|
||||
// add interceptor for each RestTemplate with @SentinelRestTemplate annotation
|
||||
StringBuilder interceptorBeanName = new StringBuilder();
|
||||
SentinelProtect sentinelProtect = cache.get(beanName);
|
||||
SentinelRestTemplate sentinelRestTemplate = cache.get(beanName);
|
||||
interceptorBeanName
|
||||
.append(StringUtils.uncapitalize(
|
||||
SentinelProtectInterceptor.class.getSimpleName()))
|
||||
.append("_")
|
||||
.append(sentinelProtect.blockHandlerClass().getSimpleName())
|
||||
.append(sentinelProtect.blockHandler()).append("_")
|
||||
.append(sentinelProtect.fallbackClass().getSimpleName())
|
||||
.append(sentinelProtect.fallback());
|
||||
.append(sentinelRestTemplate.blockHandlerClass().getSimpleName())
|
||||
.append(sentinelRestTemplate.blockHandler()).append("_")
|
||||
.append(sentinelRestTemplate.fallbackClass().getSimpleName())
|
||||
.append(sentinelRestTemplate.fallback());
|
||||
RestTemplate restTemplate = (RestTemplate) bean;
|
||||
registerBean(interceptorBeanName.toString(), sentinelProtect);
|
||||
registerBean(interceptorBeanName.toString(), sentinelRestTemplate);
|
||||
SentinelProtectInterceptor sentinelProtectInterceptor = applicationContext
|
||||
.getBean(interceptorBeanName.toString(),
|
||||
SentinelProtectInterceptor.class);
|
||||
@ -90,13 +90,13 @@ public class SentinelBeanPostProcessor implements MergedBeanDefinitionPostProces
|
||||
}
|
||||
|
||||
private void registerBean(String interceptorBeanName,
|
||||
SentinelProtect sentinelProtect) {
|
||||
SentinelRestTemplate sentinelRestTemplate) {
|
||||
// register SentinelProtectInterceptor bean
|
||||
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext
|
||||
.getAutowireCapableBeanFactory();
|
||||
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(SentinelProtectInterceptor.class);
|
||||
beanDefinitionBuilder.addConstructorArgValue(sentinelProtect);
|
||||
beanDefinitionBuilder.addConstructorArgValue(sentinelRestTemplate);
|
||||
BeanDefinition interceptorBeanDefinition = beanDefinitionBuilder
|
||||
.getRawBeanDefinition();
|
||||
beanFactory.registerBeanDefinition(interceptorBeanName,
|
||||
|
@ -22,7 +22,7 @@ import java.net.URI;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.alibaba.sentinel.annotation.SentinelProtect;
|
||||
import org.springframework.cloud.alibaba.sentinel.annotation.SentinelRestTemplate;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestExecution;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
@ -37,19 +37,19 @@ import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
/**
|
||||
* Interceptor using by SentinelProtect and SentinelProtectInterceptor
|
||||
* Interceptor using by SentinelRestTemplate
|
||||
*
|
||||
* @author fangjian
|
||||
*/
|
||||
public class SentinelProtectInterceptor implements ClientHttpRequestInterceptor {
|
||||
|
||||
private static final Logger logger = LoggerFactory
|
||||
private static final Logger logger = LoggerFactory
|
||||
.getLogger(SentinelProtectInterceptor.class);
|
||||
|
||||
private SentinelProtect sentinelProtect;
|
||||
private SentinelRestTemplate sentinelRestTemplate;
|
||||
|
||||
public SentinelProtectInterceptor(SentinelProtect sentinelProtect) {
|
||||
this.sentinelProtect = sentinelProtect;
|
||||
public SentinelProtectInterceptor(SentinelRestTemplate sentinelRestTemplate) {
|
||||
this.sentinelRestTemplate = sentinelRestTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -92,15 +92,16 @@ public class SentinelProtectInterceptor implements ClientHttpRequestInterceptor
|
||||
Object[] args = new Object[] { ex };
|
||||
// handle degrade
|
||||
if (isDegradeFailure(ex)) {
|
||||
Method method = extractFallbackMethod(sentinelProtect.fallback(),
|
||||
sentinelProtect.fallbackClass());
|
||||
Method method = extractFallbackMethod(sentinelRestTemplate.fallback(),
|
||||
sentinelRestTemplate.fallbackClass());
|
||||
if (method != null) {
|
||||
method.invoke(null, args);
|
||||
}
|
||||
}
|
||||
// handle block
|
||||
Method blockHandler = extractBlockHandlerMethod(sentinelProtect.blockHandler(),
|
||||
sentinelProtect.blockHandlerClass());
|
||||
Method blockHandler = extractBlockHandlerMethod(
|
||||
sentinelRestTemplate.blockHandler(),
|
||||
sentinelRestTemplate.blockHandlerClass());
|
||||
if (blockHandler != null) {
|
||||
blockHandler.invoke(null, args);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import org.junit.Test;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.cloud.alibaba.sentinel.annotation.SentinelProtect;
|
||||
import org.springframework.cloud.alibaba.sentinel.annotation.SentinelRestTemplate;
|
||||
import org.springframework.cloud.alibaba.sentinel.custom.SentinelAutoConfiguration;
|
||||
import org.springframework.cloud.alibaba.sentinel.custom.SentinelBeanPostProcessor;
|
||||
import org.springframework.cloud.alibaba.sentinel.custom.SentinelProtectInterceptor;
|
||||
@ -92,13 +92,13 @@ public class SentinelAutoConfigurationTests {
|
||||
static class SentinelTestConfiguration {
|
||||
|
||||
@Bean
|
||||
@SentinelProtect
|
||||
@SentinelRestTemplate
|
||||
RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@SentinelProtect(blockHandlerClass = ExceptionUtil.class, blockHandler = "handleException")
|
||||
@SentinelRestTemplate(blockHandlerClass = ExceptionUtil.class, blockHandler = "handleException")
|
||||
RestTemplate restTemplateWithBlockClass() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user