SpringBoot-Quartz,mybatis面试题及答案高级

factory.setDataSource(dataSource);

factory.setJobFactory(jobFactory);

factory.setQuartzProperties(quartzProperties());

return factory;

}

//从quartz.properties文件中读取Quartz配置属性

@Bean

public Properties quartzProperties() throws IOException {

PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();

propertiesFactoryBean.setLocation(new ClassPathResource(“/quartz.properties”));

propertiesFactoryBean.afterPropertiesSet();

return propertiesFactoryBean.getObject();

}

//配置JobFactory,为quartz作业添加自动连接支持

public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements

ApplicationContextAware {

private AutowireCapableBeanFactory beanFactory;

@Override

public void setApplicationContext(final ApplicationContext context) {

beanFactory = context.getAutowireCapableBeanFactory();

}

@Override

protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {

final Object job = super.createJobInstance(bundle);

beanFactory.autowireBean(job);

return job;

}

}

}

四、Entity类

package com.ealen.entity;

import lombok.Data;

import lombok.experimental.Accessors;

import javax.persistence.*;

import java.io.Serializable;

/**

  • 这里个人示例,可自定义相关属性

*/

@Entity

@Table(name = “JOB_ENTITY”)

@Data

@Accessors(chain = true)

public class JobEntity implements Serializable {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Integer id;

private String name; //job名称

private String jobGroup; //job组名

private String cron; //执行的cron

private String parameter; //job的参数

private String description; //job描述信息

private String vmParam; //vm参数

private String jarPath; //job的jar路径

private String status; //job的执行状态,这里我设置为OPEN/CLOSE且只有该值为OPEN才会执行该Job

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getJobGroup() {

return jobGroup;

}

public void setJobGroup(String jobGroup) {

this.jobGroup = jobGroup;

}

public String getCron() {

return cron;

}

public void setCron(String cron) {

this.cron = cron;

}

public String getParameter() {

return parameter;

}

public void setParameter(String parameter) {

this.parameter = parameter;

}

public String getDescription() {

return description;

}

public void setDescription(String description) {

this.description = description;

}

public String getVmParam() {

return vmParam;

}

public void setVmParam(String vmParam) {

this.vmParam = vmParam;

}

public String getJarPath() {

return jarPath;

}

public void setJarPath(String jarPath) {

this.jarPath = jarPath;

}

public String getStatus() {

return status;

}

public void setStatus(String status) {

this.status = status;

}

}

五、实现job接口

Job可以理解为就是一个工作任务,代码中就是一个实现了org.quartz.Job或org.quartz.StatefulJob接口的java类。当Scheduler决定运行Job时,execute()方法就会被执行。

具体可以干啥:

1、每天定时发送系统邮件

2、在指定的时刻发送一条短信给用户

3、执行完A任务后希望B任务在10秒后执行

总结就是任何java能做的任务都可以成为一个job。

package com.ealen.job;

import com.ealen.util.StringUtil;

import lombok.extern.slf4j.Slf4j;

import org.quartz.*;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Component;

import org.springframework.util.StringUtils;

import java.io.*;

import java.util.ArrayList;

import java.util.List;

import java.util.Objects;

/**

  • :@DisallowConcurrentExecution : 此标记用在实现Job的类上面,意思是不允许并发执行.

  • :注意org.quartz.threadPool.threadCount线程池中线程的数量至少要多个,否则@DisallowConcurrentExecution不生效

  • :假如Job的设置时间间隔为3秒,但Job执行时间是5秒,设置@DisallowConcurrentExecution以后程序会等任务执行完毕以后再去执行,否则会在3秒时再启用新的线程执行

*/

@DisallowConcurrentExecution

@Component

@Slf4j

public class DynamicJob implements Job {

private static final Logger log = LoggerFactory.getLogger(DynamicJob.class);

/**

  • 核心方法,Quartz Job真正的执行逻辑.

  • @param executorContext executorContext JobExecutionContext中封装有Quartz运行所需要的所有信息

  • @throws JobExecutionException execute()方法只允许抛出JobExecutionException异常

*/

@Override

public void execute(JobExecutionContext executorContext) throws JobExecutionException {

//JobDetail中的JobDataMap是共用的,从getMergedJobDataMap获取的JobDataMap是全新的对象

JobDataMap map = executorContext.getMergedJobDataMap();

String jarPath = map.getString(“jarPath”);

String parameter = map.getString(“parameter”);

String vmParam = map.getString(“vmParam”);

log.info("Running Job name : {} ", map.getString(“name”));

log.info(“Running Job description : {}”, map.getString(“jobDescription”));

log.info("Running Job group: {} ", map.getString(“jobGroup”));

log.info(String.format(“Running Job cron : %s”, map.getString(“cronExpression”)));

log.info("Running Job jar path : {} ", jarPath);

log.info("Running Job parameter : {} ", parameter);

log.info("Running Job vmParam : {} ", vmParam);

long startTime = System.currentTimeMillis();

if (!StringUtils.isEmpty(jarPath)) {

File jar = new File(jarPath);

if (jar.exists()) {

ProcessBuilder processBuilder = new ProcessBuilder();

processBuilder.directory(jar.getParentFile());

List commands = new ArrayList<>();

commands.add(“java”);

if (!StringUtils.isEmpty(vmParam)) commands.add(vmParam);

commands.add(“-jar”);

commands.add(jarPath);

if (!StringUtils.isEmpty(parameter)) commands.add(parameter);

processBuilder.command(commands);

log.info("Running Job details as follows >>>>>>>>>>>>>>>>>>>>: ");

log.info("Running Job commands : {} ", StringUtil.getListString(commands));

try {

Process process = processBuilder.start();

logProcess(process.getInputStream(), process.getErrorStream());

} catch (IOException e) {

throw new JobExecutionException(e);

}

} else throw new JobExecutionException("Job Jar not found >> " + jarPath);

}

long endTime = System.currentTimeMillis();

log.info(">>>>>>>>>>>>> Running Job has been completed , cost time : {}ms\n ", (endTime - startTime));

}

//记录Job执行内容

private void logProcess(InputStream inputStream, InputStream errorStream) throws IOException {

String inputLine;

String errorLine;

BufferedReader inputReader = new BufferedReader(new InputStreamReader(inputStream));

BufferedReader errorReader = new BufferedReader(new InputStreamReader(errorStream));

while (Objects.nonNull(inputLine = inputReader.readLine())) log.info(inputLine);

while (Objects.nonNull(errorLine = errorReader.readLine())) log.error(errorLine);

}

}

六、定义dao接口

package com.ealen.dao;

import com.ealen.entity.JobEntity;

import org.springframework.data.jpa.repository.JpaRepository;

public interface JobEntityRepository extends JpaRepository<JobEntity, Long> {

JobEntity getById(Integer id);

}

七、service 服务层

package com.ealen.service;

import com.ealen.dao.JobEntityRepository;

import com.ealen.entity.JobEntity;

import com.ealen.job.DynamicJob;

import org.quartz.*;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import java.util.List;

@Service

public class DynamicJobService {

@Autowired

private JobEntityRepository repository;

//通过Id获取Job

public JobEntity getJobEntityById(Integer id) {

return repository.getById(id);

}

//从数据库中加载获取到所有Job

public List loadJobs() {

return repository.findAll();

}

//获取JobDataMap.(Job参数对象)

public JobDataMap getJobDataMap(JobEntity job) {

JobDataMap map = new JobDataMap();

map.put(“name”, job.getName());

map.put(“jobGroup”, job.getJobGroup());

map.put(“cronExpression”, job.getCron());

map.put(“parameter”, job.getParameter());

map.put(“jobDescription”, job.getDescription());

map.put(“vmParam”, job.getVmParam());

map.put(“jarPath”, job.getJarPath());

map.put(“status”, job.getStatus());

return map;

}

//获取JobDetail,JobDetail是任务的定义,而Job是任务的执行逻辑,JobDetail里会引用一个Job Class来定义

public JobDetail getJobDetail(JobKey jobKey, String description, JobDataMap map) {

return JobBuilder.newJob(DynamicJob.class)

.withIdentity(jobKey)

.withDescription(description)

.setJobData(map)

.storeDurably()

.build();

}

//获取Trigger (Job的触发器,执行规则)

public Trigger getTrigger(JobEntity job) {

return TriggerBuilder.newTrigger()

.withIdentity(job.getName(), job.getJobGroup())

.withSchedule(CronScheduleBuilder.cronSchedule(job.getCron()))

.build();

}

//获取JobKey,包含Name和Group

public JobKey getJobKey(JobEntity job) {

return JobKey.jobKey(job.getName(), job.getJobGroup());

}

}

八、自定义工具类

package com.ealen.util;

import java.util.List;

import java.util.Map;

/**

  • 自定义枚举单例对象 StringUtil

*/

public enum StringUtil {

getStringUtil;

//是否为空

public boolean isEmpty(String str) {

return (str == null) || (str.length() == 0) || (str.equals(“”));

}

//去空格

public String trim(String str) {

return str == null ? null : str.trim();

}

//获取Map参数值

public String getMapString(Map<String, String> map) {

String result = “”;

for (Map.Entry entry : map.entrySet()) {

result += entry.getValue() + " ";

}

return result;

}

//获取List参数值

public static String getListString(List list) {

StringBuilder result = new StringBuilder();

for (String s : list) {

result.append(s).append(" ");

}

return result.toString();

}

}

九、Dto

package com.ealen.web.dto;

import lombok.Data;

import javax.validation.constraints.NotEmpty;

import javax.validation.constraints.NotNull;

@Data

public class ModifyCronDTO {

@NotNull(message = “the job id cannot be null”)

private Integer id;

@NotEmpty(message = “the cron cannot be empty”)

private String cron;

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public String getCron() {

return cron;

}

public void setCron(String cron) {

this.cron = cron;

}

}

十、Controller控制器

package com.ealen.web;

import com.ealen.dao.JobEntityRepository;

import com.ealen.entity.JobEntity;

import com.ealen.job.DynamicJob;

import com.ealen.service.DynamicJobService;

import com.ealen.web.dto.ModifyCronDTO;

import lombok.extern.slf4j.Slf4j;

import org.quartz.*;

import org.quartz.impl.matchers.GroupMatcher;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import org.springframework.validation.annotation.Validated;

import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;

import javax.validation.constraints.NotNull;

import java.util.Objects;

import java.util.Set;

@RestController

@Slf4j

public class JobController {

private static final Logger log = LoggerFactory.getLogger(JobController.class);

@Autowired

private SchedulerFactoryBean schedulerFactoryBean;

@Autowired

private DynamicJobService jobService;

@Autowired

private JobEntityRepository repository;

//初始化启动所有的Job

@PostConstruct

public void initialize() {

try {

reStartAllJobs();

log.info(“init success”);

} catch (SchedulerException e) {

log.error("printStackTrace ", e);

}

}

//根据ID重启某个Job

@RequestMapping(“/refresh/{id}”)

public String refresh(@PathVariable @NotNull Integer id) throws SchedulerException {

String result;

JobEntity entity = jobService.getJobEntityById(id);

if (Objects.isNull(entity)) return "error: id is not exist ";

synchronized (log) {

JobKey jobKey = jobService.getJobKey(entity);

Scheduler scheduler = schedulerFactoryBean.getScheduler();

scheduler.pauseJob(jobKey);

scheduler.unscheduleJob(TriggerKey.triggerKey(jobKey.getName(), jobKey.getGroup()));

scheduler.deleteJob(jobKey);

JobDataMap map = jobService.getJobDataMap(entity);

JobDetail jobDetail = jobService.getJobDetail(jobKey, entity.getDescription(), map);

if (entity.getStatus().equals(“OPEN”)) {

scheduler.scheduleJob(jobDetail, jobService.getTrigger(entity));

result = "Refresh Job : " + entity.getName() + “\t jarPath: " + entity.getJarPath() + " success !”;

} else {

result = "Refresh Job : " + entity.getName() + "\t jarPath: " + entity.getJarPath() + " failed ! , " +

"Because the Job status is " + entity.getStatus();

}

}

return result;

}

//重启数据库中所有的Job

@RequestMapping(“/refresh/all”)

public String refreshAll() {

String result;

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

最后的话

无论是哪家公司,都很重视Spring框架技术,重视基础,所以千万别小看任何知识。面试是一个双向选择的过程,不要抱着畏惧的心态去面试,不利于自己的发挥。
同时看中的应该不止薪资,还要看你是不是真的喜欢这家公司,好了希望这篇文章对大家有帮助!

部分截图:
在这里插入图片描述

pping(“/refresh/all”)

public String refreshAll() {

String result;

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-wNF7ZBdd-1711787865461)]
[外链图片转存中…(img-k6jqS1TK-1711787865461)]
[外链图片转存中…(img-doAc0u97-1711787865462)]
[外链图片转存中…(img-evbrDKd5-1711787865462)]
[外链图片转存中…(img-m9Bs9zEo-1711787865462)]
[外链图片转存中…(img-d9m5hdYY-1711787865463)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-25Ts85i2-1711787865463)]

最后的话

无论是哪家公司,都很重视Spring框架技术,重视基础,所以千万别小看任何知识。面试是一个双向选择的过程,不要抱着畏惧的心态去面试,不利于自己的发挥。
同时看中的应该不止薪资,还要看你是不是真的喜欢这家公司,好了希望这篇文章对大家有帮助!

部分截图:
[外链图片转存中…(img-VkyVgXro-1711787865464)]

  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值