问题描述:使用 @HystrixCommand 注解异步方式执行,报错误 AsyncResult is just a stab and cannot be used as complete implementation of Future
Exception in thread "main" java.lang.UnsupportedOperationException: AsyncResult is just a stab and cannot be used as complete implementation of Future
at com.netflix.hystrix.contrib.javanica.command.AsyncResult.get(AsyncResult.java:49)
at com.example.server1.UserServiceCommandTest2.testGetUserName(UserServiceCommandTest2.java:26)
at com.example.server1.UserServiceCommandTest2.main(UserServiceCommandTest2.java:32)
原因:我们使用了匿名内部类的方式继承了父类 AsyncResult 。之所以会抛出异常是因为在 AsyncResult 类中,我们调用的 get 方法就是被实现抛出异常。
AsyncResult 类的get 方法的代码如下:
@Override
public T get() throws UnsupportedOperationException {
throw new UnsupportedOperationException(ERROR_MSG);
}
解决办法:在 UserServiceCommand 类中重写继承自 AsyncResult 类的get 方法。
修复问题前的代码:
@HystrixCommand(fallbackMethod = "getUserNameError")
public Future getUserName(final Long id) throws InterruptedException, ExecutionException {
return new AsyncResult() {
@Override
public String invoke() {
int i = 1/1;//此处抛异常,测试服务降级
return "小明:" + id;
}
};
}
修复问题后的代码:
@HystrixCommand(fallbackMethod = "getUserNameError")
public Future getUserName(final Long id) throws InterruptedException, ExecutionException {
return new AsyncResult() {
@Override
public String invoke() {
int i = 1/1;//此处抛异常,测试服务降级
return "小明:" + id;
}
// 重写了 get 方法
@Override
public String get() {
return invoke();
}
};
}
完整的代码如下:
UserServiceCommand.java
package com.example.server1;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.ObservableExecutionMode;
import com.netflix.hystrix.contrib.javanica.command.AsyncResult;
import org.springframework.stereotype.Service;
import rx.Observable;
import rx.Subscriber;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import com.model.User;
/**
* 用@HystrixCommand的方式来实现
*/
@Service
public class UserServiceCommand {
/**
* 同步的方式。
* fallbackMethod定义降级
*/
@HystrixCommand(fallbackMethod = "helloFallback")
public String getUserId(String name) {
int i = 1/1; //此处把除数改为零抛异常,测试服务降级
return "你好:" + name;
}
public String helloFallback(String name) {
return "error";
}
@HystrixCommand(fallbackMethod = "getUserNameError")
public Future getUserName(final Long id) throws InterruptedException, ExecutionException {
return new AsyncResult() {
@Override
public String invoke() {
int i = 1/1;//此处把除数改为零抛异常,测试服务降级
return "小明:" + id;
}
@Override
public String get() {
return invoke();
}
};
}
public String getUserNameError(Long id) {
return "faile";
}
}
UserServiceCommandTest2.java
package com.example.server1;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class UserServiceCommandTest2 {
private UserServiceCommand userServiceCommand = new UserServiceCommand();
/**
* 测试同步
*/
public void testGetUserId() {
System.out.println("=================" + userServiceCommand.getUserId("lisi"));
}
/**
* 测试异步
*/
@Test
public void testGetUserName() throws ExecutionException, InterruptedException {
System.out.println("=================" + userServiceCommand.getUserName(30L).get());
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
UserServiceCommandTest2 userServiceCommandTest2 = new UserServiceCommandTest2();
userServiceCommandTest2.testGetUserId();
userServiceCommandTest2.testGetUserName();
}
}