Bean范围"请求"与任务调度(ThreadPoolTask​​Scheduler)

时间:2015-03-23 06:40:07

标签: java spring scheduled-tasks quartz-scheduler scheduling

需要调用范围类型为#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)

1 个答案:

答案 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);
    }
}