【发布时间】:2021-03-23 03:01:44
【问题描述】:
Spring 有 @Scheduled 注释,它使方法被称为计划作业。
是否有支持的方法在方法内识别它是由这个调度调用的,还是直接从其他代码调用的?
supported 我的意思是它不能像检查调用堆栈这样的黑客行为,或者依赖上下文中某处的 HTTP 请求等副作用。
【问题讨论】:
-
不,那是不可能的
Spring 有 @Scheduled 注释,它使方法被称为计划作业。
是否有支持的方法在方法内识别它是由这个调度调用的,还是直接从其他代码调用的?
supported 我的意思是它不能像检查调用堆栈这样的黑客行为,或者依赖上下文中某处的 HTTP 请求等副作用。
【问题讨论】:
如上所述,这是不可能的。快速思考一下您的设计,如果您想知道何时从调度程序调用它,请提取一个已调度的方法并使用添加的参数(如 fromScheduler)调用您的方法。
类似这样的:
@Scheduled
public void callAnotherMethod() {
methodYouWantToCall(true);
}
public void methodYouWantToCall(boolean fromScheduler) {
if (fromScheduler) {
log.debug("called from scheduler");
} else {
log.debug("non from scheduler");
}
}
这很麻烦,但它会避免查看堆栈跟踪。就个人而言,我认为您没有任何理由不能只使用堆栈跟踪。
boolean scheduled = Arrays.stream(Thread.currentThread().getStackTrace())
.anyMatch(stackTraceElement -> stackTraceElement.getClassName().contains(
ScheduledMethodRunnable.class.getName()));
【讨论】:
您是否尝试过使用方面?像这样的:
@Aspect
@Component
public class LogInterceptor {
private static final Logger log = LoggerFactory.getLogger(LogInterceptor.class);
@Before("execution(public * my.package.name.schedulers..*.*(..))")
public void logBeforeAllSchedulers(JoinPoint joinPoint) {
String className = joinPoint.getSignature().getDeclaringType().getSimpleName();
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
log.debug("Executing: [{}]", "class: " + className + ", method: " + methodName + ", arguments: " + Arrays.toString(args));
}
}
【讨论】: