我有一个spring组件bean,它包含一个由@HystrixCommand和FallbackMethod定义的方法methodA。bean有另一个方法methodB通过CompletableFuture.SupplyAsync(...)调用methodA。我预计Hystrix javanica会在methodA上编织方面,但是当我调试它时,我没有看到Hystrix方面被编织。
下面是一些主要的sudo代码,
测试应用程序:
package com.my.own.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = "com.my.own.test")
public class TestApplication {
public static void main(final String[] args) throws Exception {
SpringApplication.run(TestApplication.class, args);
}
}
应用程序配置:
package com.my.own.test;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@EnableAspectJAutoProxy(exposeProxy = true)
@EnableConfigurationProperties
@EnableCircuitBreaker
public class ApplicationConfig {
}
package com.my.own.test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
@EnableAsync
public class AsyncConfig {
@Value("${spring.threadpool.executor.core:10}")
private int corePoolSize;
@Value("${spring.threadpool.executor.max:20}")
private int maxPoolSize;
@Value("${spring.threadpool.executor.queue:1000}")
private int queueCapacity;
@Value("${spring.threadpool.executor.timeout:true}")
private boolean coreThreadTimeOut;
@Value("${spring.threadpool.executor.keepalive:30000}")
private int keepAlive;
@Value("${spring.threadpool.executor.prefix:ThreadPoolTaskExecutor}")
private String threadNamePrefix;
@Bean("taskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setAllowCoreThreadTimeOut(coreThreadTimeOut);
executor.setKeepAliveSeconds(keepAlive);
executor.setThreadNamePrefix(threadNamePrefix + "-");
executor.initialize();
return executor;
}
}
package com.my.own.test.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.my.own.test.core.TestProcessor;
@RestController
public class TestController {
private static Logger logger = LoggerFactory.getLogger(TestController.class);
@Autowired
TestProcessor tester;
@RequestMapping(value = "/test", method = { RequestMethod.POST })
public void test() {
tester.methodB();
}
}
package com.my.own.test.core;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
@Component
public class TestProcessor {
@Autowired
private ThreadPoolTaskExecutor executor;
public void methodB() {
final List<CompletableFuture<String>> a = new ArrayList<>();
a.add(CompletableFuture.supplyAsync(() -> methodA(), executor));
CompletableFuture.allOf(a.toArray(new CompletableFuture[a.size()])).join();
}
@HystrixCommand(fallbackMethod = "deferPushdown")
public String methodA() {
if (true) {
throw new RuntimeException();
} else {
return "methodA";
}
}
public String deferMethodA() {
return "deferMethodA";
}
}
Jan 03, 2018 2:55:55 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.util.concurrent.CompletionException: java.lang.RuntimeException] with root cause
java.lang.RuntimeException
at com.my.own.test.core.TestProcessor.methodA(TestProcessor.java:40)
at com.my.own.test.core.TestProcessor.lambda$0(TestProcessor.java:33)
at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
除非您使用aspectj编织(我认为这需要对编译步骤进行特殊处理),否则spring默认使用interface/cglib编织,这只适用于从类外部调用的第一个方法,如https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aop-dermanding-aop-proxies中所述。
总之,如果调用methodB,则不应用方面,并且从methodB到methodA的调用不符合方面拦截的条件。要激活方面,必须直接从TestProcessor类外部调用methodB。
本文向大家介绍SpringCloud 中使用 Ribbon的方法详解,包括了SpringCloud 中使用 Ribbon的方法详解的使用技巧和注意事项,需要的朋友参考一下 在前两章已经给大家讲解了Ribbon负载均衡的规则 以及 如何搭建Ribbon并调用服务,那么在这一章呢 将会给大家说一说如何在SpringCloud中去使用Ribbon。在搭建之前 我们需要做一些准备工作。 1. 搭建Eure
我使用的是Spring3.2.0。根据这个答案,我在我的注释控制器中有相同的方法,它实现接口, Spring配置包括, 当文件大小超过时,应该调用前面的方法,它应该自动处理异常,但它根本不会发生。即使发生异常,也不会调用方法。处理此异常的方法是什么?我是不是漏掉了什么? 在任何情况下都不会调用方法。 一般来说,如果可能的话,我希望每个控制器基(控制器级别)处理此异常。为此,一个注释方法应该只对该特
我比较了CompletableFuture.SupplyAsync()在以下两种情况下的行为:我设置了一个自定义ExecutorService,或者我希望我的供应商由默认的executor(如果没有指定)执行,这两种情况是forkJoinPool.commonpool() 完成了!! 所以“done”会在主执行结束后打印出来。 但如果我用:
本文向大家介绍SpringCloud用Zookeeper搭建配置中心的方法,包括了SpringCloud用Zookeeper搭建配置中心的方法的使用技巧和注意事项,需要的朋友参考一下 本文介绍了SpringCloud +Zookeeper完成配置中心,分享给大家,具有如下: 使用场景 项目配置更改不需要打包,重启 提供配置文件的可视化界面 和springcloud快速整合 为什么使用zookeep
我有下面的代码块。我得到的是的catch块没有处理它。有人能告诉我如何处理下面的块抛出的异常吗?
本文向大家介绍SpringCloud通用请求字段拦截处理方法,包括了SpringCloud通用请求字段拦截处理方法的使用技巧和注意事项,需要的朋友参考一下 背景 以SpringCloud构建的微服务系统为例,使用前后端分离的架构,每个系统都会提供一些通用的请求参数,例如移动端的系统版本信息、IMEI信息,Web端的IP信息,浏览器版本信息等,这些参数可能放在header里,也可以放在参数里,如果这