Springbootベースのタイミングタスクquartzの使い方にセンスがある

20807 ワード

抽象的な思考、差別化インタフェースの抽出と反射の応用
     java   。             、    。
           。
              。               。
           。                      。
                   。            。
           。
                   。              。
          。
          job   job   。
    job                  。

detail
具体的な業務は、主にデータのリアルタイムタイミング抽出を実現することである.次にcsvに書き込み、サーバの操作をアップロードします.ここで、抽出するテーブル名、sql、間隔時間、開始時間を含むタイミング構成は、データベース内で動的に構成されます.だから.業務はすべて共通の業務である.ビジネス上の唯一の違いは、抽出するテーブル名が異なることです.主な難点は、データベース内の構成に基づいてjobを動的に設計する方法です.コードの簡潔さと拡張性.
具体的な最後の実装方法論理はこうである.
全部で2階のタイミングタスクがあります.階層管理用タスク.1階の作業用タスク.管理職タスクjobは、データベース内の構成jobをSchedulerに初めて動的にロードし、既存のjobの構成をタイミング的にリフレッシュする責任を負います.各抽出業務のタイミング情報構成は画面中でリアルタイムに変化するからである.作業用タスクは、特定のビジネスタイプjobを呼び出す責任を負います.例えば、分類表抽出、商品表抽出などです.そうですか.構成プロパティをリアルタイムでリフレッシュする機能も備えています.また、リアルタイムのタイミングでデータを抽出するビジネスニーズを満たすことができます.
管理職jobは比較的簡単です.プロジェクトの開始です.Schedulerに管理jobを入れればいいです.ポイントは仕事用jobです.各テーブルがjobメカニズムを確立して満たすことは不可能です.自分の業務には共通性があるからです.ファイルを書いてアップロードします.どのようにコードをより簡潔で、より階層的で、より拡張的に仕事をすることができますjobは考慮に値する場所です.
まず私たちはこのようにすることができます.各ビジネスデータ抽出は、同じjobクラスを指定します.データベースに何枚のテーブルがあるかにかかわらず.いくつかの表のデータを抽出します.私たちは彼を仕事用jobに帰した.次に、ジョブ用jobで異なるテーブル名に基づいて異なるクラス名を呼び出してビジネス呼び出しを実現します.
それから.私たちは今仕事用jobに着いた.各特定のトラフィックにはcsvを書き込みftpにアップロードする操作があるからです.唯一異なるのは、各テーブルに対応するsql文で検出されたbeanが異なる可能性があることです.アップロードftpは同じです.そうですか.ビジネス・オペレーション・クラスを抽象化することもできます.ポイントは.ビジネス・オペレーション・クラスにあります.テーブル名に基づいて全クラス名を取得します.反射メカニズムを用いて異なるビジネスjobクラスオブジェクトを取得する.オブジェクトの書き込みcsv操作を実行します.次に、ビジネス・オペレーション・クラスで同じアップロード・オペレーションを実行します.これはまず煩わしい.いくつかのテーブル名があれば、いくつかのオブジェクトが必要です.これで考えてみましょう.インタフェース向けにプログラミングします.私たちのすべてのビジネスjobは同じインタフェースを実現しています.これで反射に基づいて取得したビジネスjobの全クラス名は1つしかありません.異なる全クラス名によって呼び出されるビジネスjobはまた私たちが望んでいるjobです.このようにコードは簡潔明瞭になった.また、ビジネス・オペレーション・クラスの保守性と拡張性を向上させます.よい方法であることを失わない.これが具体的なインタフェース向けです.共通の方法と差別化コードの実装を抽出する.
言葉の総括にはまだ欠けているかもしれない.しかし、コードを貼るとずっとよくなります.次は、主な方法コードをいくつか貼ります.
クラスの開始
package cn.com.winpeace.kiban.web;

import cn.com.winpeace.kiban.winperpsrv.allofpackages.CheckHead;
import cn.com.winpeace.kiban.winperpsrv.persistence.dao.AllPackagesMapper;
import cn.com.winpeace.kiban.winperpsrv.persistence.model.RealCrtMaterResultDO;
import cn.com.winpeace.kiban.winperpsrv.schedulerManager.SchedulerManager;
import cn.com.winpeace.kiban.winperpsrv.test.QuartzTriggerZero;
import cn.com.winpeace.kiban.winperpsrv.vo.JobInfoDto;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import tk.mybatis.spring.annotation.MapperScan;

import java.util.ArrayList;
import java.util.List;

/**
 * @author nehcoab
 * @date 2018/7/13
 */
@SpringBootApplication
@ComponentScan({"cn.com.winpeace.kiban"})
@MapperScan({"cn.com.winpeace.kiban.*.persistence.dao"})
public class Application {



    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);

        //      
        CheckHead checkHead = new CheckHead();
        //checkHead.checkSystemConfig();


        //      job
        RealCrtMaterResultDO realCrtMaterResultDO =
                new RealCrtMaterResultDO("RefreshJobManager", "RefreshJobManager","2019-10-13",
                        "09:16:10", 15, "1", "1",
                        "cn.com.winpeace.kiban.winperpsrv.allofpackages.ConfigurationJob");

        //       
        Scheduler scheduler = SchedulerManager.getScheduler();
        SchedulerManager.addManagerJob(scheduler, realCrtMaterResultDO);
        SchedulerManager.run(scheduler, 0);


    }
}


管理用jobコード:
package cn.com.winpeace.kiban.winperpsrv.allofpackages;
/**
 * @ClassName ConfigurationJob
 * @Description TODO
 * @Author YPF
 * @Date 2019/9/2814:04
 * @Version 1.0
 */

import cn.com.winpeace.kiban.winperpsrv.logger.MySchedulerTestLogger;
import cn.com.winpeace.kiban.winperpsrv.persistence.dao.AllPackagesMapper;
import cn.com.winpeace.kiban.winperpsrv.persistence.model.RealCrtMaterResultDO;
import cn.com.winpeace.kiban.winperpsrv.schedulerManager.SchedulerManager;
import cn.com.winpeace.kiban.winperpsrv.test.QuartzTriggerZero;
import cn.com.winpeace.kiban.winperpsrv.vo.JobInfoDto;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;

/**
 * @ClassName ConfigurationJob
 * @Description peizhiJOB         。             
 * @Author YPF
 * @Date 2019/9/2814:04
 * @Version 1.0
 **/
@Component
public class ConfigurationJob implements Job{

	@Autowired
	AllPackagesMapper allPackagesMapper;

	public static ConfigurationJob configurationJob;

	@PostConstruct
	public void init() {
		configurationJob = this;
	}

	@Override
	public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
		MySchedulerTestLogger.log("         is begin-----------------");
		refresh(jobExecutionContext);
		MySchedulerTestLogger.log("         is end-----------------");
	}
	private void refresh(JobExecutionContext jobExecutionContext) {
		try {
			//          
			List realCrtMaterResultDOS = configurationJob.allPackagesMapper.selectConfigurationMessage();

			//     
			Scheduler scheduler = jobExecutionContext.getScheduler();
			for(RealCrtMaterResultDO newJobInfo : realCrtMaterResultDOS){
				//  job    
				JobDetail job = SchedulerManager.getJobDetail(scheduler, newJobInfo);
				if(job==null){
					if(newJobInfo.getCron_status().toString().equals("1") && newJobInfo.getValid_status().toString().equals("1")){
						//  job   job    
						MySchedulerTestLogger.log("       is new JOB!" + newJobInfo.getCustomer_id() + "."
								+ newJobInfo.getIf_id());
						SchedulerManager.addJob(scheduler,newJobInfo);
					}
				}else{
					RealCrtMaterResultDO oldJobInfo = SchedulerManager.getJobInfo(job);
					if((oldJobInfo.getCron_status().toString().equals("0") && newJobInfo.getCron_status() .toString().equals("1"))
						|| (oldJobInfo.getValid_status().toString().equals("0") && newJobInfo.getValid_status() .toString().equals("1"))){
						//job         。 job    
						MySchedulerTestLogger.log("ReschedulerJob is OFF -> ON!" + job.getKey());
					}else if ((oldJobInfo.getCron_status() .toString().equals("0") && newJobInfo.getCron_status() .toString().equals("0"))
						|| (oldJobInfo.getValid_status() .toString().equals("0") && newJobInfo.getValid_status() .toString().equals("0"))){
						//job      。 job   
						MySchedulerTestLogger.log("ReschedulerJob is OFF -> OFF!" + job.getKey());
					}else if ((oldJobInfo.getCron_status() .toString().equals("1") && newJobInfo.getCron_status() .toString().equals("0"))
						|| (oldJobInfo.getValid_status() .toString().equals("1") && newJobInfo.getValid_status() .toString().equals("0"))){
						//job         。 job  
						SchedulerManager.unscheduleJob(scheduler,newJobInfo);
					}else if((oldJobInfo.getCron_status() .toString().equals("1") && newJobInfo.getCron_status()  .toString().equals("1"))
						|| (oldJobInfo.getValid_status() .toString().equals("1") && newJobInfo.getValid_status()  .toString().equals("1"))){
						//job         。     job      
						if(oldJobInfo.getCron_intervals() != newJobInfo.getCron_intervals()){
							//job    
							MySchedulerTestLogger.log("ReschedulerJob is change IntervalInSeconds!" + job.getKey());
							SchedulerManager.rescheduleJob(scheduler,newJobInfo);
						}
					}
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}


作業用jobコード:
package cn.com.winpeace.kiban.winperpsrv.allofpackages;
/**
 * @ClassName IfWorkJob
 * @Description TODO
 * @Author YPF
 * @Date 2019/10/119:45
 * @Version 1.0
 */

import cn.com.winpeace.kiban.winperpsrv.logger.MySchedulerTestLogger;
import cn.com.winpeace.kiban.winperpsrv.persistence.dao.AllPackagesMapper;
import cn.com.winpeace.kiban.winperpsrv.persistence.model.RealCrtMaterResultDO;
import cn.com.winpeace.kiban.winperpsrv.schedulerManager.SchedulerManager;
import cn.com.winpeace.kiban.winperpsrv.util.ApplicationContextProvider;
import cn.com.winpeace.kiban.winperpsrv.util.TableNameLinkWorkClassUtil;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * @ClassName IfWorkJob
 * @Description TODO
 * @Author YPF
 * @Date 2019/10/119:45
 * @Version 1.0
 **/
@Component
public class IfWorkJob implements Job {

	private static final String CURRENT_JOB_INFO_KEY = "CURRENT_JOB_INFO_KEY";

	@Autowired
	AllPackagesMapper allPackagesMapper;

	public static IfWorkJob ifWorkJob;

	@PostConstruct
	public void init() {
		ifWorkJob = this;
	}

	public void run(){
		MySchedulerTestLogger.log("IfBuyerExecute is begin-----------------");
	}
	@Override
	public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
		try{
			JobDetail jobDetail = jobExecutionContext.getJobDetail();
			RealCrtMaterResultDO jobInfo = (RealCrtMaterResultDO) jobDetail.getJobDataMap().get(CURRENT_JOB_INFO_KEY);

			CsvFTP csvFTP = (CsvFTP)ApplicationContextProvider.getBean("CsvFTP", CsvFTP.class);
			csvFTP.run(jobInfo.getIf_id());

		}catch (Exception e){
			e.printStackTrace();
		}
	}
}


ビジネスクラスコード:
package cn.com.winpeace.kiban.winperpsrv.allofpackages;
/**
 * @ClassName CsvFTP
 * @Description TODO
 * @Author YPF
 * @Date 2019/10/1311:16
 * @Version 1.0
 */

import cn.com.winpeace.kiban.winperpsrv.util.ApplicationContextProvider;
import cn.com.winpeace.kiban.winperpsrv.util.TableNameLinkWorkClassUtil;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

/**
 * @ClassName CsvFTP
 * @Description TODO
 * @Author YPF
 * @Date 2019/10/1311:16
 * @Version 1.0
 **/
@Component("CsvFTP")
@Scope("prototype")
public class CsvFTP {

		public void run(String jobInfo) throws  Exception {
			//      csv  class 
			String className = TableNameLinkWorkClassUtil.getWorkClass(jobInfo);
			//   csv  class
			IfInterfaceWorkClass csvEditClass = (IfInterfaceWorkClass) ApplicationContextProvider.getBean(jobInfo, Class.forName(className));
			//  sql 
			//  csv  
			csvEditClass.run(jobInfo);
			//ftp        
		}
}


異なるテーブル・ビジネスおよびインタフェース・コードは次のとおりです.
@Service("if_buyer")
@Scope("prototype")
public class IfBuyerExecute implements  IfInterfaceWorkClass  {

	private final static String timeFormat = "HH:mm:ss";
	public final static String shortDateFormat = "yyyy-MM-dd";
	public final static String longDateFormat = "yyyy-MM-dd HH:mm:ss";
	public final static String simpleDateFormat = "yyyyMMdd";
	public final static String completeDateFormat = "yyyyMMddHHmmssSSS";
	public final static String IFID ="if_buyer";

	private static Logger logger = StdOutErrRedirect.logger;

	public static IfBuyerExecute ifBuyerExecute;

	@PostConstruct
	public void init() {
		ifBuyerExecute = this;
	}


	@Value("${config.cronUser}")
	private String cronUser;

	@Override
	//  csv       sql --》dao-》  csv
	public void run(String jobInfo){

		MySchedulerTestLogger.log("IfBuyerExecute is begin-----------------"+jobInfo);
		PumpEnv pumpEnv = ifBuyerExecute.pumpEnvMapper.getPumpEnv();
		MySchedulerTestLogger.log(pumpEnv.toString());
	}

package cn.com.winpeace.kiban.winperpsrv.allofpackages;
/**
 * @ClassName IfCategoryExecute
 * @Description TODO
 * @Author YPF
 * @Date 2019/9/2820:16
 * @Version 1.0
 */

import cn.com.winpeace.kiban.winperpsrv.logger.MySchedulerTestLogger;
import cn.com.winpeace.kiban.winperpsrv.persistence.model.RealCrtMaterResultDO;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

/**
 * @ClassName IfCategoryExecute
 * @Description TODO
 * @Author YPF
 * @Date 2019/9/2820:16
 * @Version 1.0
 **/
@Component("if_category")
@Scope("prototype")
public class IfCategoryExecute  implements  IfInterfaceWorkClass {


	@Override
	public void run(String jobInfo){
		MySchedulerTestLogger.log("IfCategoryExecute is begin-----------------"+jobInfo);



	}


}

package cn.com.winpeace.kiban.winperpsrv.allofpackages;

import cn.com.winpeace.kiban.winperpsrv.persistence.model.RealCrtMaterResultDO;

/**
 * @ClassName ifInterfaceWorkClass
 * @Description TODO
 * @Author YPF
 * @Date 2019/10/1311:04
 * @Version 1.0
 */
public interface IfInterfaceWorkClass {

	public void run(String jobInfo);
}


jobツールクラスコード:
package cn.com.winpeace.kiban.winperpsrv.schedulerManager;



import cn.com.winpeace.kiban.winperpsrv.allofpackages.IfWorkJob;
import cn.com.winpeace.kiban.winperpsrv.persistence.model.RealCrtMaterResultDO;
import cn.com.winpeace.kiban.winperpsrv.vo.JobInfoDto;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class SchedulerManager {

	private static final String CURRENT_JOB_INFO_KEY = "CURRENT_JOB_INFO_KEY";

	/**
	 * SchedulerFactory    Scheduler      
	 * getSchedule():     
	 * @return
	 * @throws Exception
	 */
	public static Scheduler getScheduler() throws Exception {
		SchedulerFactory schedulerFactory = new StdSchedulerFactory();
		return schedulerFactory.getScheduler();
	}

	/**
	 *    scheduler   Scheduler   job  
	 * @param scheduler
	 * @param jobInfos
	 * @throws Exception
	 */
	public static void init(Scheduler scheduler,  List jobInfos) throws Exception {
		for (RealCrtMaterResultDO jobInfo : jobInfos) {
			if (jobInfo.getCron_status().toString().equals("1") && jobInfo.getValid_status().equals("1")) {
				addJob(scheduler, jobInfo);
			}
		}
	}

	/**
	 *           
	 * @param scheduler
	 * @param delayedSeconds
	 * @throws Exception
	 */
	public static void run(Scheduler scheduler, int delayedSeconds) throws Exception {

		scheduler.startDelayed(delayedSeconds);
	}

	/**
	 *       :
	 * JobDetail
	 *    job    。JobBuilder --     。    。
	 *  newJob():  job  。  JobInfoDto         。
	 *  withIdentity():   name/group
	 *  jobDetail.getJobDataMap().put():   java.util.Map   。    JobDataMap     /  ,         Job          。      Job            。
	 * Trigger:    
	 *    Job      Trigger。   Trigger       ,         。    ,     。      5。        trigger ,      :  ->   ->    
	 *  newTrigger()     。TriggerBuilder --     。    。
	 *  withIdentity():  name/group
	 *  startAt():  job           job  。  【startNow():    scheduler,    】
	 *  withSchedule():  Schedule   SimpleSchedule     ,        。
	 *  scheduleJob():  Trigger job     
	 * @param scheduler
	 * @param jobInfo
	 * @throws Exception
	 */
	public static void addJob(Scheduler scheduler, RealCrtMaterResultDO jobInfo) throws Exception {
		Class cls = (Class) Class.forName("cn.com.winpeace.kiban.winperpsrv.allofpackages.IfWorkJob");
		JobDetail jobDetail = JobBuilder.newJob(cls)
				.withIdentity(jobInfo.getIf_id(), jobInfo.getCustomer_id())
				.build();
		jobDetail.getJobDataMap().put(CURRENT_JOB_INFO_KEY, jobInfo);

		Trigger trigger = TriggerBuilder.newTrigger()
				.withIdentity(jobInfo.getIf_id(), jobInfo.getCustomer_id())
				.startAt(getStartTime(jobInfo.getCron_intervals()))
				.withSchedule(SimpleScheduleBuilder.simpleSchedule()
						.withIntervalInSeconds(jobInfo.getCron_intervals()).repeatForever())
				.build();
		scheduler.scheduleJob(jobDetail, trigger);
	}
	public static void addManagerJob(Scheduler scheduler, RealCrtMaterResultDO jobInfo) throws Exception {
		Class cls = (Class) Class.forName(jobInfo.getJobClass());
		JobDetail jobDetail = JobBuilder.newJob(cls)
				.withIdentity(jobInfo.getIf_id(), jobInfo.getCustomer_id())
				.build();
		jobDetail.getJobDataMap().put(CURRENT_JOB_INFO_KEY, jobInfo);

		Trigger trigger = TriggerBuilder.newTrigger()
				.withIdentity(jobInfo.getIf_id(), jobInfo.getCustomer_id())
				.startAt(getStartTime(jobInfo.getCron_intervals()))
				.withSchedule(SimpleScheduleBuilder.simpleSchedule()
						.withIntervalInSeconds(jobInfo.getCron_intervals()).repeatForever())
				.build();
		scheduler.scheduleJob(jobDetail, trigger);
	}


	/**
	 *   job  
	 *  JobKey:JobKey   Job       
	 *  getJobDetail();  jobkey  job  
	 *  getJobDataMap():        map key  job    
	 *        
	 *         job    
	 * @param scheduler
	 * @param jobInfo
	 * @throws Exception
	 */
	public static void rescheduleJob(Scheduler scheduler, RealCrtMaterResultDO jobInfo) throws Exception {
		JobKey jobKey = JobKey.jobKey(jobInfo.getIf_id(), jobInfo.getCustomer_id());
		JobDetail jobDetail = scheduler.getJobDetail(jobKey);
		RealCrtMaterResultDO oldJobInfo = (RealCrtMaterResultDO) jobDetail.getJobDataMap().get(CURRENT_JOB_INFO_KEY);
		oldJobInfo.setCron_intervals(jobInfo.getCron_intervals());
		oldJobInfo.setCron_date(jobInfo.getCron_date());
		oldJobInfo.setCron_time(jobInfo.getCron_time());
		
		TriggerKey triggerKey = TriggerKey.triggerKey(jobInfo.getIf_id(), jobInfo.getCustomer_id());
		Trigger trigger = TriggerBuilder.newTrigger()
				.withIdentity(jobInfo.getIf_id(), jobInfo.getCustomer_id())
				.startAt(getStartTime(jobInfo.getCron_intervals(), jobInfo.getCron_date()+" "+jobInfo.getCron_time()))
				.withSchedule(SimpleScheduleBuilder.simpleSchedule()
						.withIntervalInSeconds(jobInfo.getCron_intervals()).repeatForever())
				.build();
		scheduler.rescheduleJob(triggerKey, trigger);
	}

	/**
	 *   job    unscheduleJob  TriggerKey【deleteJob  jobKey】
	 * @param scheduler
	 * @param jobInfo
	 * @throws Exception
	 */
	public static void unscheduleJob(Scheduler scheduler, RealCrtMaterResultDO jobInfo) throws Exception {
		TriggerKey triggerKey = TriggerKey.triggerKey(jobInfo.getIf_id(), jobInfo.getCustomer_id());
		scheduler.unscheduleJob(triggerKey);  
	}

	private static Date getStartTime(int delayedSeconds) {
		Date date = new Date(System.currentTimeMillis() + 1000 * delayedSeconds);
		return date;
	}
	
	private static Date getStartTime(int intervalInSeconds, String delayedSeconds) {
		//date      
		Date date = null;
		try {
			System.out.println(delayedSeconds);
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			long time = simpleDateFormat.parse(delayedSeconds).getTime();
			long diff=0;
			if(time>System.currentTimeMillis()){
				//                   
				 diff = System.currentTimeMillis()-time;
			}
			date =  new Date(System.currentTimeMillis() + 1000 * (intervalInSeconds + diff));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}
	
	public static JobDetail getJobDetail(Scheduler scheduler, RealCrtMaterResultDO jobInfo) throws Exception {
		JobKey jobKey = JobKey.jobKey(jobInfo.getIf_id(), jobInfo.getCustomer_id());
		return scheduler.getJobDetail(jobKey);
	}
	
	public static RealCrtMaterResultDO getJobInfo(JobDetail jobDetail) throws Exception {
		return (RealCrtMaterResultDO) jobDetail.getJobDataMap().get(CURRENT_JOB_INFO_KEY);
	}
	public static long getSecond(String time){
		long s = 0;
		if(time.length()==8){ //     00:00:00
			int index1=time.indexOf(":");
			int index2=time.indexOf(":",index1+1);
			s = Integer.parseInt(time.substring(0,index1))*3600;//  
			s+=Integer.parseInt(time.substring(index1+1,index2))*60;//  
			s+=Integer.parseInt(time.substring(index2+1));// 
		}
		if(time.length()==5){//    00:00
			s = Integer.parseInt(time.substring(time.length()-2)); //          
			s+=Integer.parseInt(time.substring(0,2))*60;    //  
		}
		return s;
	}
}

一番大切なのは.インタフェース向けプログラミング.共通業務の抽出とコード差別化を実現する.ビジネスの拡張性、保守性をより簡潔に実現する方法.調査問題の難易度を下げることが重要だ.やはり思考のより抽象化が必要だ.これからもできるだけこの方面のもっと高いレベルに考えなければなりません.抽象的な業務を抽出する能力を高める.