Лямбда, поднимающаяся, является техникой для 'снимания' лямбд к более высокому уровню (главным образом к верхнему уровню).
Doug Currie описывает, почему Вы хотели бы сделать это.
Вот некоторый пример кода (в JavaScript) того, как Вы могли сделать это вручную:
function addFive(nr)
{
var x = 5;
function addX(y)
{
return x + y;
}
return addX(nr);
}
Теперь, если Вы не хотите этот addX
функция в определении addFive
, Вы могли бы 'снять' его к верхнему уровню как так:
function addX(y)
{
return x + y;
}
function addFive(nr)
{
var x = 5;
return addX(nr);
}
Однако это не будет работать, начиная с x
переменная больше не доступна в контексте эти addX
функция. Способ зафиксировать это состоит в том, чтобы добавить дополнительный формальный параметр к функции:
function addX(y, x)
{
return x + y;
}
function addFive(nr)
{
var x = 5;
return addX(nr, x);
}
<час> Дополнение: Вот является очень изобретенный пример лямбды 'выходом'. Где Вы не будете в состоянии сделать лямбду, поднимающуюся так же легко, как я описал.
function getAddFiveFunc()
{
var x = 5;
function addX(y)
{
return x + y;
}
return addX;
}
Теперь, если кто-то звонит эти getAddFiveFunc
функция, они вернут функцию. Эта функция могла использоваться во всех видах мест, Теперь, если Вы действительно хотите подняться эти addX
функция, необходимо будет обновить все те callsites.
Я использую следующий суперкласс для своих задач, которым необходим доступ к области запроса. По сути, вы можете просто расширить его и реализовать свою логику в методе onRun ().
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
/**
* @author Eugene Kuleshov
*/
public abstract class RequestAwareRunnable implements Runnable {
private final RequestAttributes requestAttributes;
private Thread thread;
public RequestAwareRunnable() {
this.requestAttributes = RequestContextHolder.getRequestAttributes();
this.thread = Thread.currentThread();
}
public void run() {
try {
RequestContextHolder.setRequestAttributes(requestAttributes);
onRun();
} finally {
if (Thread.currentThread() != thread) {
RequestContextHolder.resetRequestAttributes();
}
thread = null;
}
}
protected abstract void onRun();
}
Не могли бы вы попробовать наоборот? Используйте контейнер данных, который хранится в области запроса, и передайте его пулу потоков (возможно, поместите его в очередь, чтобы пул потоков мог принимать по одному контейнеру данных за раз, работать с ним, отмечать его как «выполненное» и продолжать со следующим).
Spring имеет класс ThreadPoolTaskExecutor , который можно использовать для управления пулом потоков из Spring. Однако похоже, что вам придется поработать, чтобы сделать контекст Spring доступным для каждого потока.
Я не уверен, что он будет работать, даже если вы подключите его таким образом. Spring использует токен в локальном потоке для поиска объектов в области запроса (или сеанса), поэтому, если вы пытаетесь получить доступ к bean-объекту области запроса из другого потока, вероятно, этого токена там не будет.