国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁(yè) > news >正文

電子商務(wù)網(wǎng)站建設(shè)個(gè)人總結(jié)推廣學(xué)院seo教程

電子商務(wù)網(wǎng)站建設(shè)個(gè)人總結(jié),推廣學(xué)院seo教程,西安網(wǎng)站建設(shè)制作價(jià)格低,新網(wǎng)域名注冊(cè)步驟前段時(shí)間編寫了一篇博客SpringBoot 動(dòng)態(tài)操作定時(shí)任務(wù)(啟動(dòng)、停止、修改執(zhí)行周期,該篇博客還是幫助了很多同學(xué)。 但是該篇博客中的方法有些不足的地方: 只能通過(guò)前端控制器controller手動(dòng)注冊(cè)任務(wù)?!揪唧w的應(yīng)該是我們提前配置好我們的任務(wù)&am…

前段時(shí)間編寫了一篇博客SpringBoot 動(dòng)態(tài)操作定時(shí)任務(wù)(啟動(dòng)、停止、修改執(zhí)行周期,該篇博客還是幫助了很多同學(xué)。
但是該篇博客中的方法有些不足的地方:

  1. 只能通過(guò)前端控制器controller手動(dòng)注冊(cè)任務(wù)?!揪唧w的應(yīng)該是我們提前配置好我們的任務(wù),配置完成后讓springboot應(yīng)用幫我們加載并注冊(cè)任務(wù)】
  2. 無(wú)法打印任務(wù)的啟動(dòng)時(shí)間、下次執(zhí)行時(shí)間及任務(wù)耗時(shí)等情況。

所以針對(duì)以上的不足我對(duì)該方案進(jìn)行了整改。

新方案涉及4個(gè)類:

  1. TaskSchedulerConfig 任務(wù)調(diào)度器及任務(wù)注冊(cè)器的配置
  2. ScheduledTaskRegistrar 任務(wù)注冊(cè)器,用于將定時(shí)任務(wù)注冊(cè)到調(diào)度器中
  3. ScheduledTaskHolder 任務(wù)的包裝類
  4. ITask 任務(wù)抽象類

提醒:該定時(shí)任務(wù)只能實(shí)現(xiàn)單機(jī)環(huán)境下使用,無(wú)法在分布式環(huán)境下使用。

一、核心實(shí)現(xiàn)如下:

1、配置類TaskSchedulerConfig

該配置類往spring容器中注冊(cè)了兩個(gè)bean,第一個(gè)bean為org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler,該bean為spring提供的基于線程池的任務(wù)調(diào)度器,其本質(zhì)是持有一個(gè)java.util.concurrent.ScheduledThreadPoolExecutor,這里需要注意初始化ScheduledThreadPoolExecutor的時(shí)候最大線程數(shù)為Integer.MAX_VALU。
setRemoveOnCancelPolicy方法如果設(shè)置為true,則在中斷當(dāng)前執(zhí)行的任務(wù)后會(huì)將其從任務(wù)等待隊(duì)列(如果隊(duì)列中有該任務(wù))中移除。
第二個(gè)bean為ScheduledTaskRegistrar即我們的任務(wù)注冊(cè)器,該bean需要持有一個(gè)任務(wù)調(diào)度器并且需要配置任務(wù)列表【目前任務(wù)列表需要手動(dòng)配置如果同學(xué)們想增強(qiáng)的話可以自己實(shí)現(xiàn)注解掃描配置或者包掃描配置】。

package com.bbs.config.scheduled;import com.bbs.task.MoniterTask;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;import java.util.Arrays;/*** @Author whh* @Date: 2023/03/15/ 20:15* @description*/
@Configuration
public class TaskSchedulerConfig {/**** 本質(zhì)是ScheduledThreadPoolExecutor的包裝,其中初始化ScheduledThreadPoolExecutor的構(gòu)造函數(shù)如下* 特別的要注意最大線程數(shù)為 Integer.MAX_VALUE**  public ScheduledThreadPoolExecutor(int corePoolSize,*                                        ThreadFactory threadFactory,*                                        RejectedExecutionHandler handler) {*         super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,*               new DelayedWorkQueue(), threadFactory, handler);*     }* @return*/@Beanpublic ThreadPoolTaskScheduler threadPoolTaskScheduler(){ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();threadPoolTaskScheduler.setPoolSize(3);threadPoolTaskScheduler.setRemoveOnCancelPolicy(true);return threadPoolTaskScheduler;}@Beanpublic ScheduledTaskRegistrar taskRegistrar(ThreadPoolTaskScheduler scheduler){ScheduledTaskRegistrar taskRegistrar = new ScheduledTaskRegistrar(scheduler);MoniterTask moniterTask = new MoniterTask("*/30 * * * * ?");moniterTask.setTaskName("監(jiān)控任務(wù)");moniterTask.setTaskDescription("每隔30s對(duì)機(jī)器進(jìn)行監(jiān)控");taskRegistrar.setTaskes(Arrays.asList(moniterTask));return taskRegistrar;}
}

2、任務(wù)注冊(cè)器ScheduledTaskRegistrar

該任務(wù)注冊(cè)器實(shí)現(xiàn)了org.springframework.beans.factory.InitializingBean接口,所以可以達(dá)到配置完成后讓springboot應(yīng)用幫我們加載并注冊(cè)任務(wù)。該bean主要有5個(gè)方法,包括注冊(cè)任務(wù)、查詢所有任務(wù)、立即執(zhí)行任務(wù)、暫停任務(wù)、任務(wù)恢復(fù)。其中立即執(zhí)行任務(wù)并未使用調(diào)度器的線程執(zhí)行而是使用用戶線程執(zhí)行。

package com.bbs.config.scheduled;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.util.StringUtils;import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;/*** @Author whh* @Date: 2023/03/15/ 19:44* @description 任務(wù)注冊(cè)*/
public class ScheduledTaskRegistrar implements InitializingBean {private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledTaskRegistrar.class);/*** 任務(wù)調(diào)度器*/private ThreadPoolTaskScheduler scheduler;/*** 任務(wù)列表*/private List<ITask> taskes;private final Map<String, ScheduledTaskHolder> register = new ConcurrentHashMap<>();public ScheduledTaskRegistrar(ThreadPoolTaskScheduler scheduler) {this.scheduler = scheduler;}/*** 注冊(cè)任務(wù)*/public void register() {for (ITask task : taskes) {ScheduledFuture<?> future = this.scheduler.schedule(task, new CronTrigger(task.getCron()));ScheduledTaskHolder holder = new ScheduledTaskHolder();holder.setScheduledFuture(future);holder.setTask(task);register.put(task.getClass().getName(), holder);}}/*** 查詢所有任務(wù)** @return*/public Collection<ScheduledTaskHolder> list() {return register.values();}/*** 立即執(zhí)行任務(wù)** @param className*/public void start(String className) {ScheduledTaskHolder holder = register.get(className);if (holder != null) {holder.getTask().run();}}/*** 暫停任務(wù)** @param className*/public void pause(String className) {ScheduledTaskHolder holder = register.get(className);if (holder != null) {if(holder.terminate()){return;}ScheduledFuture<?> future = holder.getScheduledFuture();future.cancel(true);}}/***重啟任務(wù)* @param className* @param cron*/public void restart(String className,String cron){ScheduledTaskHolder holder = register.get(className);if (holder != null) {if(!holder.terminate()){//暫停原任務(wù)holder.getScheduledFuture().cancel(true);}ITask task = holder.getTask();if(!StringUtils.isEmpty(cron)){task.setCron(cron);}ScheduledFuture<?> future = this.scheduler.schedule(task, new CronTrigger(task.getCron()));holder.setScheduledFuture(future);}}public void setTaskes(List<ITask> taskes) {this.taskes = taskes;}private void log(){register.forEach((k,v)->{LOGGER.info("register {} complete,cron {}",k,v.getTask().getCron());});}@Overridepublic void afterPropertiesSet(){register();log();}
}

3、任務(wù)包裝類ScheduledTaskHolder

任務(wù)包裝類包含具體任務(wù)的實(shí)例、任務(wù)執(zhí)行的ScheduledFuture以及任務(wù)的運(yùn)行狀態(tài)。

package com.bbs.config.scheduled;import java.util.concurrent.ScheduledFuture;/*** @Author whh* @Date: 2023/03/15/ 19:45* @description*/
public class ScheduledTaskHolder {/*** 具體任務(wù)*/private ITask task;/***result of scheduling*/private ScheduledFuture<?> scheduledFuture;public ITask getTask() {return task;}public void setTask(ITask task) {this.task = task;}public ScheduledFuture<?> getScheduledFuture() {return scheduledFuture;}public void setScheduledFuture(ScheduledFuture<?> scheduledFuture) {this.scheduledFuture = scheduledFuture;}public boolean terminate() {return scheduledFuture.isCancelled();}
}

4、 任務(wù)抽象類ITask

任務(wù)抽象類ITask實(shí)現(xiàn)了Runnable接口同時(shí)提供了抽象方法execute用于自定義任務(wù)實(shí)現(xiàn),同時(shí)對(duì)任務(wù)進(jìn)行了增強(qiáng),增加了任務(wù)執(zhí)行信息的打印。

package com.bbs.config.scheduled;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.support.SimpleTriggerContext;import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Date;/*** @Author whh* @Date: 2023/03/15/ 19:46* @description* 任務(wù)的抽象類* 用于做切面打印任務(wù)執(zhí)行的時(shí)間,耗時(shí)等信息*/
public abstract class ITask implements Runnable{private static final Logger LOGGER = LoggerFactory.getLogger("ITask");private String cron;private String taskName;private String taskDescription;public ITask(String cron) {this.cron = cron;}@Overridepublic void run() {LocalDateTime start = LocalDateTime.now();execute();LocalDateTime end = LocalDateTime.now();Duration duration = Duration.between(start, end);long millis = duration.toMillis();Date date = new CronTrigger(this.cron).nextExecutionTime(new SimpleTriggerContext());LOGGER.info("任務(wù):[{}]執(zhí)行完畢,開(kāi)始時(shí)間:{},結(jié)束時(shí)間:{},耗時(shí):{}ms,下次執(zhí)行時(shí)間{}",this.taskName, start,end,millis,date);}/*** 用戶的任務(wù)實(shí)現(xiàn)*/public abstract void execute();public String getCron() {return cron;}public void setCron(String cron) {this.cron = cron;}public String getTaskName() {return taskName;}public void setTaskName(String taskName) {this.taskName = taskName;}public String getTaskDescription() {return taskDescription;}public void setTaskDescription(String taskDescription) {this.taskDescription = taskDescription;}
}

二、前端控制器TaskController

package com.bbs.task.controller;import com.bbs.config.scheduled.ITask;
import com.bbs.config.scheduled.ScheduledTaskRegistrar;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.support.SimpleTriggerContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;/*** @Author whh* @Date: 2023/03/15/ 21:18* @description*/
@RestController
@RequestMapping("/task")
public class TaskController {@Autowiredprivate ScheduledTaskRegistrar scheduledTaskRegistrar;@GetMappingpublic List<Map<String,Object>> listTask(){return scheduledTaskRegistrar.list().stream().map(e->{Map<String,Object> temp = new HashMap<>();ITask task = e.getTask();temp.put("任務(wù)名",task.getTaskName());temp.put("任務(wù)描述",task.getTaskDescription());temp.put("cron表達(dá)式",task.getCron());temp.put("任務(wù)狀態(tài)",e.terminate()?"已停止":"運(yùn)行中");temp.put("任務(wù)類名",task.getClass().getName());temp.put("下次執(zhí)行時(shí)間",new CronTrigger(task.getCron()).nextExecutionTime(new SimpleTriggerContext()));return temp;}).collect(Collectors.toList());}@PostMapping("/pause")public void pause(String className){scheduledTaskRegistrar.pause(className);}@PostMapping("/start")public void start(String className){scheduledTaskRegistrar.start(className);}@PostMapping("/restart")public void restart(String className,String cron){scheduledTaskRegistrar.restart(className,cron);}
}

三、自定義任務(wù)實(shí)現(xiàn)

package com.bbs.task;import com.bbs.config.scheduled.ITask;/*** @Author whh* @Date: 2023/03/15/ 21:16* @description*/
public class MonitorTask extends ITask {public MonitorTask(String cron) {super(cron);}@Overridepublic void execute() {System.out.println("hello world ....");}
}

四、測(cè)試

1、應(yīng)用啟動(dòng)時(shí)控制臺(tái)會(huì)打印我們注冊(cè)的任務(wù)信息
在這里插入圖片描述
2、任務(wù)執(zhí)行情況
在這里插入圖片描述
3、前端控制器查詢?nèi)蝿?wù)
在這里插入圖片描述
調(diào)用暫停API后任務(wù)停止執(zhí)行,重啟任務(wù)后任務(wù)又重新開(kāi)始執(zhí)行。
在這里插入圖片描述

http://m.aloenet.com.cn/news/33079.html

相關(guān)文章:

  • 網(wǎng)站工商備案查詢2020年關(guān)鍵詞排名
  • 如何做一個(gè)網(wǎng)頁(yè)布局如何快速優(yōu)化網(wǎng)站排名
  • 做熟食的網(wǎng)站美食網(wǎng)站東莞最新消息今天
  • 有哪些學(xué)做衣服的網(wǎng)站網(wǎng)站推廣如何引流
  • 淘寶網(wǎng)站建設(shè)協(xié)議谷歌瀏覽器下載手機(jī)版安卓官網(wǎng)
  • 昭陽(yáng)區(qū)住房和城鄉(xiāng)建設(shè)管理局網(wǎng)站重慶關(guān)鍵詞seo排名
  • 京東網(wǎng)上商城投訴電話天津seo托管
  • 網(wǎng)站開(kāi)發(fā)地圖板塊浮動(dòng)青島谷歌優(yōu)化
  • 旅游網(wǎng)站制作百度云網(wǎng)站搜索排名優(yōu)化軟件
  • 定制網(wǎng)站建設(shè)報(bào)價(jià)單網(wǎng)址導(dǎo)航下載到桌面
  • 原創(chuàng)網(wǎng)站模版營(yíng)銷策劃方案模板范文
  • 溫州專業(yè)網(wǎng)站建設(shè)推廣seo信息是什么
  • 南通企業(yè)網(wǎng)頁(yè)制作江西省seo
  • 大連日文網(wǎng)站設(shè)計(jì)營(yíng)銷型網(wǎng)站建設(shè)策劃書
  • 做網(wǎng)站工具免費(fèi)的seo優(yōu)化工具
  • 哪個(gè)網(wǎng)站可以免費(fèi)做H51+x網(wǎng)店運(yùn)營(yíng)推廣
  • 邢臺(tái)做網(wǎng)站建設(shè)優(yōu)化制作公司企業(yè)建站 平臺(tái)
  • 網(wǎng)站推廣什么意思百度搜圖匹配相似圖片
  • 常州網(wǎng)站優(yōu)化營(yíng)銷軟文小短文
  • 怎么注冊(cè)公司教程鄭州seo排名扣費(fèi)
  • 付費(fèi)的網(wǎng)站是指seo網(wǎng)站排名助手
  • 40萬(wàn)用戶自助建站seo根據(jù)什么具體優(yōu)化
  • 手機(jī)端公司網(wǎng)站怎么做seo快速排名優(yōu)化方法
  • 前端后端四川seo整站優(yōu)化
  • iis網(wǎng)站壓縮百度搜索次數(shù)統(tǒng)計(jì)
  • 東營(yíng)建設(shè)信息網(wǎng)公示專業(yè)整站優(yōu)化
  • php模板網(wǎng)站營(yíng)銷推廣計(jì)劃怎么寫
  • ps怎么網(wǎng)站首頁(yè)網(wǎng)店推廣運(yùn)營(yíng)
  • 一浪網(wǎng)站建設(shè)競(jìng)價(jià)網(wǎng)站
  • 網(wǎng)站優(yōu)化吧推廣發(fā)布任務(wù)平臺(tái)app下載