展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > SpringBoot动态定时任务如何实现

SpringBoot动态定时任务如何实现

执行定时任务的线程池配置类importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.scheduling.TaskScheduler;importorg.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;@Configura

本文目录

     执行定时任务的线程池配置类

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.TaskScheduler;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
     
    @Configuration
    public class SchedulingConfig {  
        @Bean
        public TaskScheduler taskScheduler() {
            ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
            // 定时任务执行线程池核心线程数  
            taskScheduler.setPoolSize(6);  
            taskScheduler.setRemoveOnCancelPolicy(true);  
            taskScheduler.setThreadNamePrefix("TaskSchedulerThreadPool-");  
            return taskScheduler;  
        }  
    }

    ScheduledFuture的包装类

    ScheduledFuture是ScheduledExecutorService定时任务线程池的执行结果。

    import java.util.concurrent.ScheduledFuture;
     
    public final class ScheduledTask {
      
        volatile ScheduledFuture future;
        /**  
         * 取消定时任务  
         */  
        public void cancel() {  
            ScheduledFuture future = this.future;  
            if (future != null) {  
                future.cancel(true);  
            }  
        }  
    }

    Runnable接口实现类

    被定时任务线程池调用,用来执行指定bean里面的方法。

    import com.ying.demo.utils.springContextUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.util.ReflectionUtils;
    import org.springframework.util.StringUtils;
    import java.lang.reflect.Method;
    import java.util.Objects;
     
    public class SchedulingRunnable implements Runnable {
     
       private static final Logger logger = LoggerFactory.getLogger(SchedulingRunnable.class);
     
       private String beanName;
     
       private String methodName;
     
       private String params;
     
       public SchedulingRunnable(String beanName, String methodName) {
          this(beanName, methodName, null);
       }
     
       public SchedulingRunnable(String beanName, String methodName, String params) {
          this.beanName = beanName;
          this.methodName = methodName;
          this.params = params;
       }
     
       @Override
       public void run() {
          logger.info("定时任务开始执行 - bean:{},方法:{},参数:{}", beanName, methodName, params);
          long startTime = System.currentTimeMillis();
     
          try {
             Object target = springContextUtils.getBean(beanName);
     
             Method method = null;
             if (!StringUtils.isEmpty(params)) {
                method = target.getClass().getDeclaredMethod(methodName, String.class);
             } else {
                method = target.getClass().getDeclaredMethod(methodName);
             }
     
             ReflectionUtils.makeAccessible(method);
             if (!StringUtils.isEmpty(params)) {
                method.invoke(target, params);
             } else {
                method.invoke(target);
             }
          } catch (Exception ex) {
             logger.error(String.format("定时任务执行异常 - bean:%s,方法:%s,参数:%s ", beanName, methodName, params), ex);
          }
     
          long times = System.currentTimeMillis() - startTime;
          logger.info("定时任务执行结束 - bean:{},方法:{},参数:{},耗时:{} 毫秒", beanName, methodName, params, times);
       }
     
       @Override
       public boolean equals(Object o) {
          if (this == o) return true;
          if (o == null || getClass() != o.getClass()) return false;
          SchedulingRunnable that = (SchedulingRunnable) o;
          if (params == null) {
             return beanName.equals(that.beanName) &&
                   methodName.equals(that.methodName) &&
                   that.params == null;
          }
     
          return beanName.equals(that.beanName) &&
                methodName.equals(that.methodName) &&
                params.equals(that.params);
       }
     
       @Override
       public int hashCode() {
          if (params == null) {
             return Objects.hash(beanName, methodName);
          }
     
          return Objects.hash(beanName, methodName, params);
       }
    }

    定时任务注册类

    用来增加、删除定时任务

    @Component
    public class CronTaskRegistrar implements DisposableBean {
     
       private final Map scheduledTasks = new ConcurrentHashMap<>(16);
     
       @Autowired
       private TaskScheduler taskScheduler;
     
       public TaskScheduler getScheduler() {
          return this.taskScheduler;
       }
     
       public void addCronTask(Runnable task, String cronExpression) {
          addCronTask(new CronTask(task, cronExpression));
       }
     
       public void addCronTask(CronTask cronTask) {
          if (cronTask != null) {
             Runnable task = cronTask.getRunnable();
             if (this.scheduledTasks.containsKey(task)) {
                removeCronTask(task);
             }
     
             this.scheduledTasks.put(task, scheduleCronTask(cronTask));
          }
       }
     
       public void removeCronTask(Runnable task) {
          ScheduledTask scheduledTask = this.scheduledTasks.remove(task);
          if (scheduledTask != null)
             scheduledTask.cancel();
       }
     
       public ScheduledTask scheduleCronTask(CronTask cronTask) {
          ScheduledTask scheduledTask = new ScheduledTask();
          scheduledTask.future = this.taskScheduler.schedule(cronTask.getRunnable(), cronTask.getTrigger());
     
          return scheduledTask;
       }
     
     
       @Override
       public void destroy() {
          for (ScheduledTask task : this.scheduledTasks.values()) {
             task.cancel();
          }
     
          this.scheduledTasks.clear();
       }
    }

    定时任务示例类

    @Slf4j
    @Component("taskDemo")
    public class Task1 {  
        public void taskByParams(String params) {
            log.info("taskByParams执行时间:{}", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            log.info("taskByParams执行有参示例任务:{}",params);
        }  
      
        public void taskNoParams() {
            log.info("taskByParams执行时间:{}", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            log.info("taskNoParams执行无参示例任务");
        }
     
        public void test(String params) {
            log.info("test执行时间:{}", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            log.info("test执行有参示例任务:{}",params);
        }
    }

    数据库表设计

    CREATE TABLE `schedule_setting` (
      `job_id` int NOT NULL AUTO_INCREMENT COMMENT '任务ID',
      `bean_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'bean名称',
      `method_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '方法名称',
      `method_params` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '方法参数',
      `cron_expression` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'cron表达式',
      `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注',
      `job_status` int DEFAULT NULL COMMENT '状态(1正常 0暂停)',
      `create_time` datetime DEFAULT NULL COMMENT '创建时间',
      `update_time` datetime DEFAULT NULL COMMENT '修改时间',
      PRIMARY KEY (`job_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

    实体类

    @Data
    public class ScheduleSetting extends Model {
       /**
        * 任务ID
        */
       @Id
       private Integer jobId;
       /**
        * bean名称
        */
       private String beanName;
       /**
        * 方法名称
        */
       private String methodName;
       /**
        * 方法参数
        */
       private String methodParams;
       /**
        * cron表达式
        */
       private String cronExpression;
       /**
        * 状态(1正常 0暂停)
        */
       private Integer jobStatus;
       /**
        * 备注
        */
       private String remark;
       /**
        * 创建时间
        */
       private Date createTime;
       /**
        * 更新时间
        */
       private Date updateTime;
    }

    定时任务预热

    spring boot项目启动完成后,加载数据库里状态为正常的定时任务

    @Service  
    public class SysJobRunner implements CommandLineRunner {  
      
        private static final Logger logger = LoggerFactory.getLogger(SysJobRunner.class);  
      
        @Autowired  
        private CronTaskRegistrar cronTaskRegistrar;  
      
        @Override  
        public void run(String... args) {  
            // 初始加载数据库里状态为正常的定时任务  
            ScheduleSetting existedSysJob = new ScheduleSetting();
            List jobList = existedSysJob.selectList(new QueryWrapper().eq("job_status", 1));
            if (CollectionUtils.isNotEmpty(jobList)) {  
                for (ScheduleSetting job : jobList) {  
                    SchedulingRunnable task = new SchedulingRunnable(job.getBeanName(), job.getMethodName(), job.getMethodParams());  
                    cronTaskRegistrar.addCronTask(task, job.getCronExpression());  
                }  
                logger.info("定时任务已加载完毕...");  
            }  
        }  
    }

    工具类

    用来从spring容器里获取bean

    @Component  
    public class SpringContextUtils implements ApplicationContextAware {  
      
        private static ApplicationContext applicationContext;  
      
        @Override  
        public void setApplicationContext(ApplicationContext applicationContext)  
                throws BeansException {  
            SpringContextUtils.applicationContext = applicationContext;  
        }  
      
        public static Object getBean(String name) {  
            return applicationContext.getBean(name);  
        }  
      
        public static  T getBean(Class requiredType) {  
            return applicationContext.getBean(requiredType);  
        }  
      
        public static  T getBean(String name, Class requiredType) {  
            return applicationContext.getBean(name, requiredType);  
        }  
      
        public static boolean containsBean(String name) {  
            return applicationContext.containsBean(name);  
        }  
      
        public static boolean isSingleton(String name) {  
            return applicationContext.isSingleton(name);  
        }  
      
        public static Class getType(String name) {  
            return applicationContext.getType(name);  
        }  
    }

    定时任务的:增/删/改/启动/暂停

    @RestController
    public class TestController {
     
       @Autowired
       private CronTaskRegistrar cronTaskRegistrar;
     
       /**
        * 添加定时任务
        *
        * @param sysJob
        * @return
        */
       @PostMapping("add")
       public boolean add(@RequestBody ScheduleSetting sysJob) {
          sysJob.setCreateTime(new Date());
          sysJob.setUpdateTime(new Date());
     
          boolean insert = sysJob.insert();
          if (!insert) {
             return false;
          }else {
             if (sysJob.getJobStatus().equals(1)) {// 添加成功,并且状态是1,直接放入任务器
                SchedulingRunnable task = new SchedulingRunnable(sysJob.getBeanName(), sysJob.getMethodName(), sysJob.getMethodParams());
                cronTaskRegistrar.addCronTask(task, sysJob.getCronExpression());
             }
          }
          return insert;
       }
     
       /**
        * 修改定时任务
        *
        * @param sysJob
        * @return
        */
       @PostMapping("update")
       public boolean update(@RequestBody ScheduleSetting sysJob) {
          sysJob.setCreateTime(new Date());
          sysJob.setUpdateTime(new Date());
     
          // 查询修改前任务
          ScheduleSetting existedSysJob = new ScheduleSetting();
          existedSysJob = existedSysJob.selectOne(new QueryWrapper().eq("job_id", sysJob.getJobId()));
          // 修改任务
          boolean update = sysJob.update(new UpdateWrapper().eq("job_id", sysJob.getJobId()));
          if (!update) {
             return false;
          } else {
             // 修改成功,则先删除任务器中的任务,并重新添加
             SchedulingRunnable task1 = new SchedulingRunnable(existedSysJob.getBeanName(), existedSysJob.getMethodName(), existedSysJob.getMethodParams());
             cronTaskRegistrar.removeCronTask(task1);
             if (sysJob.getJobStatus().equals(1)) {// 如果修改后的任务状态是1就加入任务器
                SchedulingRunnable task = new SchedulingRunnable(sysJob.getBeanName(), sysJob.getMethodName(), sysJob.getMethodParams());
                cronTaskRegistrar.addCronTask(task, sysJob.getCronExpression());
             }
          }
          return update;
       }
     
       /**
        * 删除任务
        *
        * @param jobId
        * @return
        */
       @PostMapping("del/{jobId}")
       public boolean del(@PathVariable("jobId") Integer jobId) {
          // 先查询要删除的任务信息
          ScheduleSetting existedSysJob = new ScheduleSetting();
          existedSysJob = existedSysJob.selectOne(new QueryWrapper().eq("job_id", jobId));
     
          // 删除
          boolean del = existedSysJob.delete(new QueryWrapper().eq("job_id", jobId));
          if (!del)
             return false;
          else {// 删除成功时要清除定时任务器中的对应任务
             SchedulingRunnable task = new SchedulingRunnable(existedSysJob.getBeanName(), existedSysJob.getMethodName(), existedSysJob.getMethodParams());
             cronTaskRegistrar.removeCronTask(task);
          }
          return del;
       }
     
       // 停止/启动任务
       @PostMapping("changesStatus/{jobId}/{stop}")
       public boolean changesStatus(@PathVariable("jobId") Integer jobId, @PathVariable("stop") Integer stop) {
          // 修改任务状态
          ScheduleSetting scheduleSetting = new ScheduleSetting();
          scheduleSetting.setJobStatus(stop);
          boolean job_id = scheduleSetting.update(new UpdateWrapper().eq("job_id", jobId));
          if (!job_id) {
             return false;
          }
          // 查询修改后的任务信息
          ScheduleSetting existedSysJob = new ScheduleSetting();
          existedSysJob = existedSysJob.selectOne(new QueryWrapper().eq("job_id", jobId));
     
          // 如果状态是1则添加任务
          if (existedSysJob.getJobStatus().equals(1)) {
             SchedulingRunnable task = new SchedulingRunnable(existedSysJob.getBeanName(), existedSysJob.getMethodName(), existedSysJob.getMethodParams());
             cronTaskRegistrar.addCronTask(task, existedSysJob.getCronExpression());
          } else {
             // 否则清除任务
             SchedulingRunnable task = new SchedulingRunnable(existedSysJob.getBeanName(), existedSysJob.getMethodName(), existedSysJob.getMethodParams());
             cronTaskRegistrar.removeCronTask(task);
          }
          return true;
       }

    SpringBoot动态定时任务如何实现

    cron

    cron表达式语法:

    [秒] [分] [小时] [日] [月] [周] [年]

     注:[年]不是必须的域,可以省略[年],则一共6个域

    SpringBoot动态定时任务如何实现

    通配符说明:

    • * 表示所有值。 例如:在分的字段上设置 *,表示每一分钟都会触发。

    • ? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作,但不关心是周几,所以需要周位置的那个字段设置为”?” 具体设置为 0 0 0 10 * ?

    • - 表示区间。例如 在小时上设置 “10-12”,表示 10,11,12点都会触发。

    • , 表示指定多个值,例如在周字段上设置 “MON,WED,FRI” 表示周一,周三和周五触发

    • / 用于递增触发。如在秒上面设置”5/15” 表示从5秒开始,每增15秒触发(5,20,35,50)。 在日字段上设置’1/3’所示每月1号开始,每隔三天触发一次。

    • L 表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,如果是二月还会依据是否是润年[leap]), 在周字段上表示星期六,相当于”7”或”SAT”。如果在”L”前加上数字,则表示该数据的最后一个。例如在周字段上设置”6L”这样的格式,则表示“本月最后一个星期五”

    • W 表示离指定日期的最近那个工作日(周一至周五). 例如在日字段上置”15W”,表示离每月15号最近的那个工作日触发。如果15号正好是周六,则找最近的周五(14号)触发, 如果15号是周未,则找最近的下周一(16号)触发.如果15号正好在工作日(周一至周五),则就在该天触发。如果指定格式为 “1W”,它则表示每月1号往后最近的工作日触发。如果1号正是周六,则将在3号下周一触发。(注,”W”前只能设置具体的数字,不允许区间”-“)。

    • # 序号(表示每月的第几个周几),例如在周字段上设置”6#3”表示在每月的第三个周六.注意如果指定”#5”,正好第五周没有周六,则不会触发该配置(用在母亲节和父亲节再合适不过了) ;小提示:’L’和 ‘W’可以一组合使用。如果在日字段上设置”LW”,则表示在本月的最后一个工作日触发;周字段的设置,若使用英文字母是不区分大小写的,即MON与mon相同。

    示例:

    每隔5秒执行一次:*/5 * * * * ?

    每隔1分钟执行一次:0 */1 * * * ?

    每天23点执行一次:0 0 23 * * ?

    每天凌晨1点执行一次:0 0 1 * * ?

    每月1号凌晨1点执行一次:0 0 1 1 * ?

    每月最后一天23点执行一次:0 0 23 L * ?

    每周星期六凌晨1点实行一次:0 0 1 ? * L

    在26分、29分、33分执行一次:0 26,29,33 * * * ?

    每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ?

    cron在线表达式生成器:http://tools.jb51.net/code/Quartz_Cron_create

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。

    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    Maya(Autodesk Maya) Windows版
    Maya(Autodesk Maya) Windows版

    Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。