我使用的是org.springframework.boot
版本"2.3.3.RELEASE"。当我在ProcessService类上运行集成测试时,我会得到错误:
java.lang.IllegalStateException: Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available, and ensure that AopContext.currentProxy() is invoked in the same thread as the AOP invocation context.
at org.springframework.aop.framework.AopContext.currentProxy(AopContext.java:69)
这是主要类别:
@EnableRetry
@EnableScheduling
@SpringBootApplication
@EnableRedNotificationService
@EnableAspectJAutoProxy(exposeProxy = true)
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
服务类获取错误:
@Slf4j
@Service
public class ProcessService {
@Retryable(maxAttemptsExpression = "${api.retry.limit}", backoff = @Backoff(delayExpression = "${api.retry.max-interval}",
multiplierExpression = "${api.retry.delay-multiplier}", maxDelayExpression = "${api.retry.max-delay}"))
public void triggerJob(Parameters...) throws Exception {
// Some code
method1();
// some code
}
public JobResult method1(Parameters.. ) {
ProcessService processService = (ProcessService) AopContext.currentProxy();
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<JobResult> task = executorService.submit(() -> processService.method2(Parameters..));
// some code
}
@Retryable(maxAttemptsExpression = "${api.retry.limit}", backoff = @Backoff(delayExpression = "${api.retry.max-interval}",
multiplierExpression = "${api.retry.delay-multiplier}", maxDelayExpression = "${api.retry.max-delay}"))
JobResult method2(Parameters.. ) {
// Some code
}
}
关于如何解决这个问题,有什么建议吗?我应该如何模拟方法1中的AopContext.currentProxy()
调用以返回ProcessService类的对象?目前,在测试执行时,execution正在org.springframework.aop.framework.AopContext类的currentProxy((方法中执行,并返回null。
public static Object currentProxy() throws IllegalStateException {
Object proxy = currentProxy.get();
if (proxy == null) {
throw new IllegalStateException(
"Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available, and " +
"ensure that AopContext.currentProxy() is invoked in the same thread as the AOP invocation context.");
}
return proxy;
}
在集成测试中,我必须创建一个AopContext的Mock静态并返回该类。
@Mock
private MockedStatic<AopContext> aopContextMockedStatic;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
processService = spy(new ProcessService(InputPraramters...));
aopContextMockedStatic.when(AopContext::currentProxy).thenReturn(processService);
}
@AfterEach
void tearDownStatic() {
aopContextMockedStatic.close();
}
看起来@EnableAspectJAutoProxy(exposeProxy=true(在Spring Boot 中与@EnableAsync不起作用
我创建了这样一个助手类来委托我的异步操作
@Slf4j
@Component
public class AsyncHelper {
@Async
public <T> CompletableFuture<T> supplyAsync(Supplier<T> supplier) {
log.info("supplyAsync invoked");
return CompletableFuture.supplyAsync(supplier);
}
@Async
public void runAsync(Runnable runnable) {
log.info("runAsync invoked");
CompletableFuture.runAsync(runnable);
}
}
现在,我从目标类中删除了@Async注释,并调用助手,如以下代码所示:
protected CompletableFuture<String> doSupplyAsyncUsingHelper() {
return asyncHelper.supplyAsync(() -> {
doSomething();
return "Something";
});
}
protected void doRunAsyncUsingHelper() {
asyncHelper.runAsync(() -> {
doSomething();
doSomethingElse();
});
}