Необходимо вызвать 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)
У нас была такая же проблема несколько лет назад. Мы исправили это путем рефакторинга приложения. Мы создали настраиваемый контекст-объект, который передается службам и репозиториям.
Этот контекст был сопоставлен с атрибутами запроса и сеанса при выходе из 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);
}
}