2020-03-16 12:54
@JFinal 倒也是,依赖太多违背精简思想,但是插件机制不知是否有问题,
现在有个bug,用JfinalConfig配置注册插件quartz调度不行,而且启动时也不报错,日志也是DEBUG等级
/**
* 配置插件
*/
public void configPlugin(Plugins me) {
QuartzPlugin quartz = new QuartzPlugin();
me.add(quartz);
}
但是改在main 调用就可以,太诡异。。。
/**
* 启动入口,运行此 main 方法可以启动项目
*/
public static void main(String[] args){
UndertowServer.start(AppConfig.class);
QuartzPlugin quartz = new QuartzPlugin();
quartz.start();
}
2020-03-16 10:17
@JFinal 波总,主要Cron4jPlugin 不支持秒级调度,不然肯定首选官方插件啊。波总秒级调度还是比较常见的场景啊
2020-03-15 15:29
任务死活不执行,找了半天没找到原因,求助大佬 @JFinal @埋头苦干
====================== QuartzPlugin =====================
package com.wjme.app.job.plugin;
import com.jfinal.kit.LogKit;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.IPlugin;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class QuartzPlugin implements IPlugin {
private List jobs = new ArrayList();
private SchedulerFactory sf;
public static Scheduler scheduler;
private String jobConfig;
private String confConfig;
private Properties jobProp;
public QuartzPlugin(String jobConfig, String confConfig) {
this.jobConfig = jobConfig;
this.confConfig = confConfig;
}
public QuartzPlugin(String jobConfig) {
this.jobConfig = jobConfig;
this.confConfig = "quartz.properties";
}
public QuartzPlugin() {
this.jobConfig = "quartz.properties";
this.confConfig = "quartz.properties";
}
public static void addJob(JobBean job) {
try {
TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobDesc(), job.getJobGroup());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 不存在,创建一个
if (null == trigger) {
Class j2 = (Class) Class.forName(job.getJobClass());
JobDetail jobDetail = JobBuilder.newJob(j2).withIdentity(job.getJobDesc(), job.getJobGroup()).build();
jobDetail.getJobDataMap().put("scheduleJob", job);
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
// 按新的cronExpression表达式构建一个新的trigger
trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobDesc(), job.getJobGroup())
.withSchedule(scheduleBuilder).build();
try {
scheduler.scheduleJob(jobDetail, trigger);
} catch (Exception e) {
e.printStackTrace();
LogKit.error("", e);
}
} else {
// Trigger已存在,那么更新相应的定时设置
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
// 按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
}
} catch (Exception e) {
e.printStackTrace();
LogKit.error("", e);
}
}
@Override
public boolean start() {
loadJobsFromProperties();
startJobs();
return true;
}
private void startJobs() {
try {
if (StrKit.notBlank(confConfig)) {
sf = new StdSchedulerFactory(confConfig);
} else {
sf = new StdSchedulerFactory();
}
scheduler = sf.getScheduler();
} catch (SchedulerException e) {
e.printStackTrace();
LogKit.error("", e);
}
for (JobBean entry : jobs) {
addJob(entry);
}
try {
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
LogKit.error("", e);
}
}
private void loadJobsFromProperties() {
if (StrKit.isBlank(jobConfig)) {
return;
}
jobProp = PropKit.use(jobConfig).getProperties();
String jobArray = PropKit.use(jobConfig).get("jobArray");
if (StrKit.isBlank(jobArray)) {
return;
}
String[] jobArrayList = jobArray.split(",");
for (String jobName : jobArrayList) {
jobs.add(createJobBean(jobName));
}
}
private JobBean createJobBean(String key) {
JobBean job = new JobBean();
job.setJobGroup(key);
job.setJobClass(jobProp.getProperty(key + ".job" , ""));
job.setCronExpression(jobProp.getProperty(key + ".cron" , ""));
job.setJobDesc(jobProp.getProperty(key + ".desc" , ""));
return job;
}
@Override
public boolean stop() {
try {
scheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
LogKit.error("", e);
}
return true;
}
}
============ job 类====================
package com.wjme.app.job;
import com.jfinal.kit.HttpKit;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.PropKit;
import com.jfinal.server.undertow.UndertowConfig;
import com.wjme.App;
import com.wjme.app.busi.DataInfo;
import com.wjme.app.util.DES3Util;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AutoIP implements Job {
Logger log = LoggerFactory.getLogger(getClass());
private static String currIP = "";
private String serverPath = PropKit.get("serverPath");
private String clientPath = PropKit.get("clientPath");
private int cPort = new UndertowConfig(App.class).getPort();
private int port =PropKit.getInt("clientPort", cPort);
private boolean clientRedirect =PropKit.getBoolean("clientPort", false);
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("xxxxx");
}
}
===============JfinalConfig ====================
/**
* 配置插件
*/
public void configPlugin(Plugins me) {
QuartzPlugin quartz = new QuartzPlugin();
me.add(quartz);
}
=================quartz.properties ======================
#开启的任务列表“,”隔开
jobArray = autoip
autoip.job=com.wjme.app.job.AutoIP
autoip.cron= 0/10 * * * * ?
autoip.desc=autoip
#============================================================================
# 配置主要调度程序属性
#============================================================================
org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.instanceId = AUTO
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false
#============================================================================
# 配置线程池
#============================================================================
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 5
#============================================================================
# 配置任务
#============================================================================
org.quartz.jobStore.misfireThreshold = 1800
org.quartz.scheduler.skipUpdateCheck = true
2017-09-30 08:56
@JFinal 建议波总默认多加一些序列化的实现,如
/**
* 验证码
*/
public class Captcha 类
在做一些服务化框架和缓存处理时没办法直接用,还需创建子类再实现序列化使用
2017-09-28 15:05
@JFinal 哈哈,已采用如下方式:
public void afterJFinalStart() {
try {
JFinal.me().getConstants().setCaptchaCache(new RedisCaptchaCache());
RedisCaptchaCache.setCaptchaCache(Redis.use("captcha"));
} catch (TemplateModelException e) {
e.printStackTrace();
}
}