我有以下类(简化)可以使用Java和Spring工具箱实现异步方法调用。我需要添加一些在异步方法调用之前和之后执行的逻辑。
可通话。如果可以访问数据,我可以把我需要的逻辑放在这里。
public class ContextAwareCallable<T> implements Callable<T> {
private Callable<T> task;
private MyContext context;
public ContextAwareCallable(Callable<T> task, MyContext context) {
this.task = task;
this.context = context;
}
@Override
public T call() throws Exception {
return task.call();
}
}
这是执行程序,其中调用了任务。
public class ContextAwarePoolExecutor extends ThreadPoolTaskExecutor {
private static final long serialVersionUID = 1L;
@Override
public <T> Future<T> submit(Callable<T> task) {
return super.submit(new ContextAwareCallable<T>(task, myContext));
}
这是配置程序。初始化执行程序。据我了解,我可以将TaskDecorator放在这里,儿子,我可以在里面做我需要的逻辑。不过,我仍然需要无法从TaskDecorator内部访问的方法中的数据。
@EnableAsync
@Configuration
public class MyAsyncPoolConfig implements AsyncConfigurer {
@Override
@Bean("DefaultAsyncTaskExecutor")
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(0);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(10);
executor.setThreadNamePrefix("myPrefix");
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new MyAsyncUncaughtExceptionHandler();
}
}
异步方法本身。
@Service("TESTCOMPONENT_ASYNC_SERVICE_METHOD_CALL")
@Async("TESTCOMPONENT_ASYNCTESTER_ASYNC_POOL")
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Throwable.class)
public Future<AsyncCallMethodOutput> asyncMethodCall(AsyncCallMethodInput methodInput) throws MyException {
// actual thing done here
}
这是调用异步方法的地方。
AsyncServiceExampleService asyncServiceExample = SpringApplicationContext.getContext().getBean(AsyncServiceExampleService.class);
我需要访问AsyncCallMethodInput
参数或更好的参数,将@Service
,ContextAwarePoolExecutor
或ContextAwareCallable
内的TaskDecorator
批注的值添加到配置程序中。
这可以通过将它们添加到上下文中并复制到线程中来完成,但是我需要在Executor或Callable内部添加此逻辑,因为这些是通用方法,并且可以提供不同的异步方法。因此,我不想强迫方法编写者向上下文中添加不应手动更改的额外数据。
有没有办法做到这一点?
答案 0 :(得分:0)
我找到了可行的解决方案。也许会有更好的解决方案,但这就是我唯一能找到的解决方案。
Spring用另一个类包装$ heroku config:set RAILS_MASTER_KEY=<your-master-key-here>
,该类具有名为Callable<T> task
的属性。当我调试时,此方法包含我的userDeclaredMethod
和我需要的所有元数据。所以我需要做的就是访问这些数据。
经过更多研究,我发现了以下方法,即方法。
asyncMethodCall
当我按以下方式调用此方法时,我能够得到所需的东西。
private static Object getField(Object c, String name) throws IllegalAccessException {
while (c != null && !c.getClass().getName().toLowerCase().equals("java.lang.object")) {
try {
Field field = c.getClass().getDeclaredField(name);
field.setAccessible(true);
return field.get(c);
} catch (NoSuchFieldException e) {
c = c.getClass().getSuperclass();
}
}
return null;
}
请注意,所有这些代码都在Method asyncMethod = (Method) getField(task, "val$userDeclaredMethod");
类中。