我有一个场景,如果某个方法有特定的注释,则需要调用该方法。该方法还需要在一个单独的线程中运行,因此我使用了@Async
,但它并不是同时运行的。
如果未使用java.lang.reflect.Method.invoke
并且使用了旧的Object.methodName()
,则该方法会异步运行。
这种情况有限制吗?我正在使用JDK 1.7和Spring 4.x。
我在applicationContext.xml中有以下内容:
<task:annotation-driven />
该类(基本上是一个监听器/回调):
@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);
}
}
}
}
}