Потеря ApplicationContext при выполнении новых исполняемых файлов - PullRequest
0 голосов
/ 11 сентября 2018

Я знаю, что я новичок в этом весеннем деле, но я застрял в этом весь день. Я не очень люблю задавать вопросы, но, возможно, у меня возникнет идея.

Итак, вот моя проблема: Я пытаюсь создать очередь для обработки вещей на серверной части. Я сделал это, создав статический executorservice в классе компонентов с вспомогательными методами для их запуска. кажется, что он работает так, как я хочу, и когда я подключаюсь к классам, я могу попасть в эти классы, но кажется, что когда они работают, они теряют контекст приложения (или что-то, что я только догадываюсь).

Я уверен, что есть лучшие способы сделать это, но в пользовательской среде, в которой я работаю, есть ряд функций, которые не будут работать для меня. У меня нет spring-config.xml, я не могу использовать @Configuration

компонент службы исполнителя

@Component
public class FifoComponent {
public static ExecutorService executors = Executors.newSingleThreadExecutor();
private static Lock lock = new ReentrantLock(true);

public static void executeNewTestJob(int i) {
    lock.lock();
    OrderAllocationTestJob job = new OrderAllocationTestJob(i);
    executors.execute(job);
    lock.unlock();
}
}

Runnable компонент - примечание appdateutils имеет метод, который вызывает компонент, который отлично работает в моей типичной среде tomcat

@Component
public class OrderAllocationTestJob implements Runnable {
int i;

public OrderAllocationTestJob(int i) {
    this.i = i;
}

@Override
public void run() {
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println("Asynchronous task " + i);
    System.out.println(AppDateUtils.getCurrentTimeStamp());
}
}

вызов из действия Struts 2 (тест). Я знаю, что могу вызвать метод appdateutils.gettime из

    for (int i = 0; i < 50; i++) {
        FifoComponent.executeNewTestJob(i);
    }

вот исключение, которое я заканчиваю тем, что оно стоит «Область запроса не активна для текущего потока»

Exception in thread "pool-15-thread-50" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dateTimestampDao': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is 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.

Ответы [ 4 ]

0 голосов
/ 19 сентября 2018

Вы ищете что-то подобное?

@ Компонент открытый класс AsynchronousThread расширяет поток {

public static final Logger LOGGER = LoggerFactory
        .getLogger(AsynchronousThread.class);

@Autowired
private Writer writer;


private BlockingQueue<IndexContextDTO> blockingQueue = new LinkedBlockingQueue<IndexContextDTO>(
        500);

/**
 * 
 */
public AsynchronousThread() {
    super("AsynchronousThread");
}


@PostConstruct
public void init() {
    Integer internalQueueSize = 100;
    this.blockingQueue = new LinkedBlockingQueue<>(internalQueueSize);
    this.start();
}


@Override
public void run() {

    while (true) {
        // Do stuff
    }
}


public void putInQueue(IndexContextDTO message) {
    try {
        this.blockingQueue.put(message);
    } catch (InterruptedException interruptedException) {
        // This exception will be thrown in very rare case.
        LOGGER.error("An error while putting message in the queue. "
                + message, interruptedException);
    }
}

}

0 голосов
/ 11 сентября 2018

Я думаю, что если вы удалите

Thread.sleep(100);

в OrderAllocationTestJob to

job.sleep(100);

в FifoComponent решит вашу проблему

0 голосов
/ 12 сентября 2018

Я решил это решение, расширив ConcurrentLinkedQueue для моих исполняемых объектов и сохранив их в диспетчере, который я создал в методе инициализации ServletContextListener. Переопределив метод offer () класса ConcurrentLinkedQueue для непрерывного опроса, пока очередь не опустела, я смог синхронно обрабатывать исполняемые объекты.

К сожалению, это блокирует поток запросов до тех пор, пока не будет выполнен исполняемый файл, и мне нужно, чтобы мои пользователи следили за ним и сообщали мне, если страницы заканчиваются долго, но, по крайней мере, в моей тестовой среде процесс кажется субсекунды, даже когда я нажал 20 раз, так что я в порядке на данный момент.

Я все же предпочел бы, чтобы ExecutorService выполнялся из моего контейнера Tomcat, но выходит за рамки запросов, но если кто-то не может ответить на вопрос, мне просто придется сейчас его оставить

0 голосов
/ 11 сентября 2018

«Я уверен, что есть лучшие способы сделать это»

Исходя из этого, вам нужно будет создать / просмотреть все компоненты области запроса и сеанса, прежде чем вызывать другой поток. На самом деле, внедрение запроса является локальным потоком и не может работать в вашем сценарии.

...