gpt4 book ai didi

java - Spring @Async 不允许使用 Autowiring 的 bean

转载 作者:搜寻专家 更新时间:2023-10-31 20:00:15 25 4
gpt4 key购买 nike

<分区>

我有一个完全注解驱动的 Spring Boot 1.3.5 应用程序,它有一个异步服务,需要 Autowiring 另一个服务 bean(将来它需要 Autowiring 一个存储库 bean,但我还没有) 以执行一些业务逻辑:

@Service
public class AsyncService {

@Autowired
public HelpingService helpingService;

@Async
public Future<String> doFoo(String someArgument)
throws InterruptedException {
Thread.sleep(3000);
System.out.println("about to do Foo "+someArgument);
String result = "";

try {
result = helpingService.getSomeStuff(someArgument);
}
catch (Exception e) {
e.printStackTrace();
}
return new AsyncResult<String>(hello);
}
}

上面的方法是从 @Controller bean 调用的,它有其他端点(非异步)也可以按预期工作

@Controller
public class MyController extends BaseController {

@Autowired
HelpingService helpingService;
@Autowired
AsyncService asyncService;

@RequestMapping(method=RequestMethod.GET, value={"/rest/threads/getIp/{jobId}"}, produces={"application/json"})
public ResponseEntity<?> getLog(@PathVariable("jobId") String jobId) throws InterruptedException {
asyncService.doFoo(jobId);
return new ResponseEntity<>(HttpStatus.OK);
}
}

这里是 helpingService 的实现(它是一个接口(interface)),当我没有从上面的 @Async 方法调用任何方法时,调用任何方法都可以正常工作:

@Service
@Validated
public class HelpingServiceImpl implements HelpingService {

@Autowired
HttpSession httpSession;

@Value(value="${projName}")
private String projName;

public String getServerAddress(){
AuthRegion region = (AuthRegion) httpSession.getAttribute("region");
if (region != null)
return region.getServerAddress();
else
return null;
}


@Override
public String getSomeStuff(String jobId) {
String responseString = "";

String projName = this.projName;
String serverAddress = getServerAddress(); // Code stops here with an exception

// Some code here that works fine outside this thread

return responseString;
}
}

这是被捕获的异常:

about to do Foo (267)
java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
at org.springframework.web.context.support.WebApplicationContextUtils.currentRequestAttributes(WebApplicationContextUtils.java:309)
at org.springframework.web.context.support.WebApplicationContextUtils.access$400(WebApplicationContextUtils.java:64)
at org.springframework.web.context.support.WebApplicationContextUtils$SessionObjectFactory.getObject(WebApplicationContextUtils.java:366)
at org.springframework.web.context.support.WebApplicationContextUtils$SessionObjectFactory.getObject(WebApplicationContextUtils.java:361)
at org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler.invoke(AutowireUtils.java:307)
at com.sun.proxy.$Proxy96.getAttribute(Unknown Source)
at corp.fernandopcg.myapp.service.ThreadServiceImpl.getRundeckServerPort(ThreadServiceImpl.java:45)
at corp.fernandopcg.myapp.service.ThreadServiceImpl.getJobExecutionOutput(ThreadServiceImpl.java:65)
at corp.fernandopcg.myapp.service.AsyncService.doFoo(AsyncService.java:40)
at corp.fernandopcg.myapp.service.AsyncService$$FastClassBySpringCGLIB$$7e164220.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:115)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
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)

我添加了(有一些更改,因为我无法在 SpringBootServletInitializer 的同时扩展 AsyncConfigurer,而且我不得不捕获那里没有提到的异常)taskExecutor 部分到我的应用程序主类如下,由 this tutorial 引导在我看来,这确实与我需要的相似

@SpringBootApplication
@EnableAsync
@EnableJpaRepositories(repositoryFactoryBeanClass = DataTablesRepositoryFactoryBean.class)
public class MyApplication extends SpringBootServletInitializer implements AsyncConfigurer{

public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}

@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("SomeRandomLookup-");
executor.initialize();
return executor;
}

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
// TODO Auto-generated method stub
return null;
}

}

我可以告诉我的@Async 服务能够使用该应用程序的其他服务吗?因为如果那不可能,我就不会真正看到这些线程机制的用途。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com