热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

spring源码深入理解(一):定时任务自定义注解及任务及同一时间多任务执行

spring定时任务-源码解析spring定时任务-几种使用前言利用spring定时任务源码解析出,自己定义注解,达到同一实践多任务的执行自定义注

spring定时任务-源码解析
spring定时任务-几种使用


前言

利用spring定时任务源码解析出,自己定义注解,达到同一实践多任务的执行


自定义注解

自己做一个自己需要的注解 ,并且可以采用源码中的方式进行管理


  • 将ScheduledAnnotationBeanPostProcessor 类复制 重改名字
  • 定义ScheduledAnnotation 注解
  • postProcessAfterInitialization 中的代码修改
  • 按照自己代码需要修改

&#64;Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {if (bean instanceof AopInfrastructureBean || bean instanceof TaskScheduler|| bean instanceof ScheduledExecutorService) {// Ignore AOP infrastructure such as scoped proxies.return bean;}Class<?> targetClass &#61; AopProxyUtils.ultimateTargetClass(bean);if (!this.nonAnnotatedClasses.contains(targetClass)) {Map<Method, Set<ScheduledAnnotation>> annotatedMethods &#61; MethodIntrospector.selectMethods(targetClass,(MethodIntrospector.MetadataLookup<Set<ScheduledAnnotation>>) method -> {Set<ScheduledAnnotation> scheduledMethods &#61; AnnotatedElementUtils.getMergedRepeatableAnnotations(method, ScheduledAnnotation.class,ScheduledAnnotations.class);return (!scheduledMethods.isEmpty() ? scheduledMethods : null);});if (annotatedMethods.isEmpty()) {this.nonAnnotatedClasses.add(targetClass);if (logger.isTraceEnabled()) {logger.trace("No &#64;Scheduled annotations found on bean class: " &#43; targetClass);}} else {// Non-empty set of methodsannotatedMethods.forEach((method, scheduledMethods) -> scheduledMethods.forEach(scheduled -> processScheduled(scheduled, method, bean)));if (logger.isTraceEnabled()) {logger.trace(annotatedMethods.size() &#43; " &#64;Scheduled methods processed on bean &#39;" &#43; beanName &#43; "&#39;: "&#43; annotatedMethods);}}}return bean;}

自定义规则


  • 解析完任务 并自定义好规则进行 将任务放到注册器中&#xff1b;
  • 上篇文章中动态添加任务到注册器中&#xff0c;相对于隔绝了需要管理任务注册器&#xff0c;并且任务注册器会自动删除任务&#xff0c;也不需要自己清理任务&#xff0c;当然自己清理那最好&#xff0c;因为spring的注解解析器&#xff0c;就是自己也会管理这些任务&#xff0c;并在销毁时清理。

/*** 解析任务并对添加入注册器中* * &#64;param scheduled* &#64;param method* &#64;param taskList* &#64;param bean*/protected void processScheduled(ScheduledAnnotation scheduled, Method method, Object bean) {try {Runnable runnable &#61; createRunnable(bean, method);boolean processedSchedule &#61; false;String errorMessage &#61; "Exactly one of the &#39;cron&#39;, &#39;fixedDelay(String)&#39;, or &#39;fixedRate(String)&#39; attributes is required";Set<ScheduledTask> tasks &#61; new LinkedHashSet<>(4);// Determine initial delaylong initialDelay &#61; scheduled.initialDelay();String initialDelayString &#61; scheduled.initialDelayString();if (StringUtils.hasText(initialDelayString)) {Assert.isTrue(initialDelay < 0, "Specify &#39;initialDelay&#39; or &#39;initialDelayString&#39;, not both");if (this.embeddedValueResolver !&#61; null) {initialDelayString &#61; this.embeddedValueResolver.resolveStringValue(initialDelayString);}if (StringUtils.hasLength(initialDelayString)) {try {initialDelay &#61; parseDelayAsLong(initialDelayString);} catch (RuntimeException ex) {throw new IllegalArgumentException("Invalid initialDelayString value \"" &#43; initialDelayString&#43; "\" - cannot parse into long");}}}

自定义注解一定要屏蔽下面代码


  • 你在使用EnableScheduling 开启spring的注解解释器时&#xff0c;会执行两个任务

在这里插入图片描述


实践问题


  • 多个任务同一时间执行问题
    由于初始化任务 java.util.concurrent .ScheduledThreadPoolExecutor 默认为单线程的线程池
  • 可以采用 在创建的时候自定义核心线程数的大小
    自定义注解器中ScheduledTaskParser设置
    在这里插入图片描述
  • 在实现SchedulingConfigurer 接口里面会获得任务注册器 也可以修改到核心线程数的大小
  • Spring是通过动态创建调度器 所以也可以注册bean的方式

一个任务执行时间如果超过了间隔时间


  • cron表达式 源码定点去执行
  • cron都是按照整点来运行的&#xff0c;比如5秒一次&#xff0c;他会在0,5,10…秒运行&#xff0c;如果任务时间点还没运行结束&#xff0c;那么就会跳过这次任务。

动态添加任务到注册器中 做定时任务


  • Spring自定义ScheduledTaskParser&#xff08;注解任务解析器&#xff09;执行任务之前&#xff0c;会调用实现SchedulingConfigurer接口的configureTasks方法&#xff0c;
  • 我们可以自定义实现SchedulingConfigurer
    接口就能做添加任务进去&#xff0c;并且这个bean要交给spring进行管理&#xff0c;并且也可以设置其核心线程数

推荐阅读
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有