Multithreading java.lang.reflect.Method.invoke和Spring@Async
我有一个场景,如果一个方法有一个特定的注释,就需要调用它。该方法还需要在单独的线程中运行,因此我使用了@Async,但是,它不是并发运行的 如果未使用java.lang.reflect.Method.invoke,并且使用了良好的旧Object.methodName,则该方法将异步运行 在这种情况下是否有限制?我正在使用JDK1.7和Spring4.x applicationContext.xml中有以下内容: 该类基本上是一个侦听器/回调:Multithreading java.lang.reflect.Method.invoke和Spring@Async,multithreading,spring,asynchronous,reflection,java.util.concurrent,Multithreading,Spring,Asynchronous,Reflection,Java.util.concurrent,我有一个场景,如果一个方法有一个特定的注释,就需要调用它。该方法还需要在单独的线程中运行,因此我使用了@Async,但是,它不是并发运行的 如果未使用java.lang.reflect.Method.invoke,并且使用了良好的旧Object.methodName,则该方法将异步运行 在这种情况下是否有限制?我正在使用JDK1.7和Spring4.x applicationContext.xml中有以下内容: 该类基本上是一个侦听器/回调: @Service @BackgroundJob p
@Service
@BackgroundJob
public class ItemHold {
private XLogger logger = XLoggerFactory.getXLogger(ItemHoldAnnotation.class
.getName());
@Async
private void doItemHoldCheck() {
try {
Thread.sleep(30 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@BackgroundJobCallback
public void mangoesTasteGood() {
logger.error("...tick...");
doItemHoldCheck();
}
}
呼叫者:
@Service
public class BatchServiceAnnotationImpl implements BatchService {
private XLogger logger = XLoggerFactory
.getXLogger(BatchServiceAnnotationImpl.class.getName());
@Inject
ApplicationContext context;
Map<Object, Method> mJobMap = new HashMap<Object, Method>();
@Scheduled(cron = "0/5 * * * * ?")
public void timer() {
performBatchJobs();
}
private void performBatchJobs() {
for (Map.Entry<Object, Method> entry : mJobMap.entrySet()) {
try {
Object object = entry.getKey();
Method method = entry.getValue();
method.invoke(object, null);
} catch (IllegalAccessException e) {
throw new AppServiceException(
"Failed to perform Background Job", e);
} catch (IllegalArgumentException e) {
throw new AppServiceException(
"Failed to perform Background Job", e);
} catch (InvocationTargetException e) {
throw new AppServiceException(
"Failed to perform Background Job", e);
}
}
}
@PostConstruct
public void init() {
/*
* Annotation based: Detect any Bean having BackgroundJob annotation.
* Then find the method annotated with BackgroundJobCallback.
*/
Map<String, Object> beans = context
.getBeansWithAnnotation(BackgroundJob.class);
for (Map.Entry<String, Object> entry : beans.entrySet()) {
Object backgroundJob = entry.getValue();
Class<?> clazz = backgroundJob.getClass();
for (Method method : clazz.getDeclaredMethods()) {
if (method.isAnnotationPresent(BackgroundJobCallback.class)) {
mJobMap.put(backgroundJob, method);
}
}
}
}
}
希望您使用注释@enableasync启用了异步支持。您能展示一些调用@Async方法的代码吗?您知道Spring通常如何通过使用代理来实现对@Async的支持吗?如果你在代理上使用反射,你可能会得到奇怪的结果。@JohnR我已经用相关代码更新了问题。你是如何在映射中获得方法实例的?@JohnR,有一个带有@PostConstruct的方法,我正在那里找到bean和方法。您必须在BatchServiceAnnotationImpl中向下滚动