top.magicpotato.fast.quartz.annotation.QuartzBeanPostProcessor Maven / Gradle / Ivy
The newest version!
package top.magicpotato.fast.quartz.annotation;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.AopInfrastructureBean;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.MethodIntrospector;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.util.StringUtils;
import top.magicpotato.fast.quartz.job.StdJob;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
/**
* @author ycl
* 用来 获取并处理 {@link QuartzScheduled} 标记的方法 放入调度器中
*/
public class QuartzBeanPostProcessor implements BeanPostProcessor {
private final Logger logger = LoggerFactory.getLogger(getClass());
private Scheduler scheduler;
public QuartzBeanPostProcessor(Scheduler scheduler) {
this.scheduler = scheduler;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof AopInfrastructureBean || bean instanceof TaskScheduler ||
bean instanceof ScheduledExecutorService) {
// Ignore AOP infrastructure such as scoped proxies.
return bean;
}
// 如果是代理类 则获取真实类
Class> targetClass = AopProxyUtils.ultimateTargetClass(bean);
// 排除不可能存在 QuartzScheduled 注解的类
if (!AnnotationUtils.isCandidateClass(targetClass, Collections.singleton(QuartzScheduled.class))) {
return bean;
}
// 在类上寻找包含注解的方法
Map annotatedMethods = MethodIntrospector.selectMethods(targetClass,
(MethodIntrospector.MetadataLookup) method -> AnnotationUtils.findAnnotation(method, QuartzScheduled.class));
if (annotatedMethods.isEmpty()) {
return bean;
}
String className = targetClass.getName();
// 循环找到的方法,加入定时计划
annotatedMethods.forEach((method, anno) -> {
// 获取任务名字、组
String name = StringUtils.hasLength(anno.name()) ? anno.name() : method.getName();
String group = StringUtils.hasLength(anno.group()) ? anno.group() : className;
// 创建job
JobDetail jobDetail = JobBuilder.newJob(StdJob.class)
.withIdentity(name, group)
.usingJobData("beanName", beanName)
.usingJobData("className", className)
.usingJobData("methodName", method.getName())
.build();
// 解析调度表达式
CronScheduleBuilder cronSchedule = CronScheduleBuilder.cronSchedule(anno.cron());
switch (anno.misfire()) {
case withMisfireHandlingInstructionDoNothing:
cronSchedule.withMisfireHandlingInstructionDoNothing();
break;
case withMisfireHandlingInstructionFireAndProceed:
cronSchedule.withMisfireHandlingInstructionFireAndProceed();
break;
case withMisfireHandlingInstructionIgnoreMisfires:
cronSchedule.withMisfireHandlingInstructionIgnoreMisfires();
break;
default:
logger.debug("采用默认补救策略");
}
// 创建触发器
Trigger trigger = TriggerBuilder.newTrigger()
// 使用方法完全限定名当作 id,以便发现重复任务
.withIdentity(name, group)
.withSchedule(cronSchedule)
.build();
try {
if (!scheduler.checkExists(jobDetail.getKey())) {
// 任务不存在才进行加入任务
scheduler.scheduleJob(jobDetail, trigger);
} else {
logger.error("任务{}已被其他节点创建", jobDetail.getKey().getName());
}
} catch (SchedulerException e) {
e.printStackTrace();
}
});
return bean;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy