需要调用范围类型为#34的bean;请求"来自任务计划程序。我知道这种类型的方法在它自己的线程中运行,并且不知道应用程序上下文。
我是否可以获得一些其他替代方法的反馈,这些方法将使我能够定义具有范围的bean" request"在一个应该定期调用的方法中?
Bean" ConnectionRepository"在下面的方法中依赖于具有Scope" Request"的另一个Bean,这会导致java.lang.IllegalStateException: No thread-bound request found
异常
OauthRefreshTask类
public class OauthRefreshTask implements Runnable, ApplicationContextAware{
private transient AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext(final ApplicationContext context) {
beanFactory = context.getAutowireCapableBeanFactory();
}
@Override
public void run() {
ConnectionRepository connectionRepository = beanFactory.getBean(ConnectionRepository.class);
...
}
}
控制器类
@Controller
public class HomeController {
private ApplicationContext appContext;
@Inject
public HomeController(ApplicationContext appContext) {
this.appContext = appContext;
}
@RequestMapping("/")
public String home(HttpServletRequest request,Principal currentUser, Model model) {
try {
task();
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "home";
}
private void task() throws SchedulerException{
OauthRefreshTask oauthRefreshTask = new OauthRefreshTask();
oauthRefreshTask.setApplicationContext(appContext);
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.initialize();
threadPoolTaskScheduler.setPoolSize(5);
long timer = 1000;
threadPoolTaskScheduler.scheduleAtFixedRate(new OauthRefreshTask(), new Date(), timer);
}
栈跟踪
ERROR: org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task.
java.lang.NullPointerException
at org.springframework.social.sample.account.OauthRefreshTask.run(OauthRefreshTask.java:26)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
答案 0 :(得分:1)
几年前我们遇到了同样的问题。我们通过重构应用程序来修复它。我们已经创建了一个自定义上下文对象,该对象将传递给服务和repos。
当来自webapp时,该上下文是从请求和会话属性映射的。并且它来自计划任务时使用工厂方法创建。
也许这不是最正确的解决方案,但它对我们有用。所以也许你可以考虑类似的重构。
@Service
public class MyService {
public void do(MyContext context) {
// Do stuff with values from the context
}
}
public class MyTask {
@Autowired MyService myService;
public void doSomething() {
MyContext context = new MyContext("defaultRequestValue");
myService.do(context);
}
}
@Controller
public class MyController {
@Autowired MyService myService;
public void handleRequest(HttpServletRequest request) {
MyContext context = new MyContext(request.getParameter("theParam"));
myService.do(context);
}
}