Recently I came across a minor inconvenience while integrating an extension to a Spring Boot application. I was given an @Autowired TaskDecorator in Spring. The goal was to execute a Supplier<T> task within the decorator through a dedicated ExecutorService.

And here’s the solution that bridges both interfaces:

// provided
@Autowired
TaskDecorator decorator;

// extension
Supplier<T> task;
ExecutorService executor;

// integration
AtomicReference<T> resultRef = new AtomicReference<>();
Runnable taskDecorated = decorator.decorate(() -> resultRef.set(task.get()));
Future<T> asyncResult = executor.submit(() -> {
  taskDecorated.run();
  return resultRef.get();
});
T result = asyncResult.get();

The TaskDecorator API only accepts Runnable. And since we want to return a value, we’ll need to capture the result in an AtomicReference object.