Бин с областью «Запрос» с планированием задач (ThreadPoolTaskScheduler)

1

Необходимо вызвать bean-компонент с типом запроса типа "запрос" из Планировщика заданий. Я знаю, что этот тип метода работает в нем собственный поток и не знает контекста приложения.

Могу ли я получить некоторую обратную связь по любым другим альтернативным подходам, которые позволят мне определить компонент с "запросом" области внутри метода aa, который должен вызываться периодически?

Бин "ConnectionRepository" в следующем методе зависит от другого компонента Bean, который имеет "запрос", который вызывает java.lang.IllegalStateException: No thread-bound request found исключение, 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
    Это просто никогда не сработает. Когда запланированный / асинхронный поток выполняется, больше нет области запроса и, следовательно, больше нет объектов области запроса. Он просто не будет и не может работать с объектами в области запроса.
  • 0
    Во время выполнения нет запроса и, следовательно, нет объема запроса. Это будет работать, только если вы передадите нужные значения другому объекту или непосредственно в контекстную карту для выполнения. Объем запроса просто не будет работать.
Теги:
spring
quartz-scheduler
scheduled-tasks
scheduling

1 ответ

0

У нас была такая же проблема несколько лет назад. Мы исправили это путем рефакторинга приложения. Мы создали настраиваемый контекст-объект, который передается службам и репозиториям.

Этот контекст был сопоставлен с атрибутами запроса и сеанса при выходе из 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);
    }
}
  • 0
    @StefannNeyts У вас есть пример?
  • 0
    Добавлен код, чтобы показать основную идею ...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню