Scheduler定時(shí)任務(wù)調(diào)度詳解
Scheduler定時(shí)任務(wù)調(diào)度
定時(shí)任務(wù)調(diào)度服務(wù)層SysJobServiceImpl
- scheduler.clear();
- scheduler.checkExists(jobKey)
- ScheduleUtils.createScheduleJob(scheduler, job);
- scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup));
- scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup));
- scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup));
- JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup);
- scheduler.triggerJob(jobKey, dataMap);
- CronUtils.isValid(cronExpression)
@Service public class SysJobServiceImpl implements ISysJobService{ @Autowired private Scheduler scheduler;//quartz-2.3.2 @Autowired private SysJobMapper jobMapper; /** 項(xiàng)目啟動(dòng)時(shí),初始化定時(shí)器 主要是防止手動(dòng)修改數(shù)據(jù)庫(kù)導(dǎo)致未同步到定時(shí)任務(wù)處理(注:不能手動(dòng)修改數(shù)據(jù)庫(kù)ID和任務(wù)組名,否則會(huì)導(dǎo)致臟數(shù)據(jù)) */ @PostConstruct public void init()throws SchedulerException,TaskException{ scheduler.clear(); List<SysJob> jobList = jobMapper.selectJobAll(); for(SysJob job : jobList){ ScheduleUtils.createScheduleJob(scheduler, job); } } /** 獲取quartz調(diào)度器的計(jì)劃任務(wù)列表 */ @Override public List<SysJob> selectJobList(SysJob job){ return jobMapper.selectJobList(job); } /** * 通過(guò)調(diào)度任務(wù)ID查詢(xún)調(diào)度信息 * * @param jobId 調(diào)度任務(wù)ID * @return 調(diào)度任務(wù)對(duì)象信息 */ @Override public SysJob selectJobById(Long jobId) { return jobMapper.selectJobById(jobId); } /** 暫停任務(wù) */ @Override @Transactional(rollbackFor = Exception.class) public int pause(SysJob job)throws SchedulerException{ Long jobId = job.getJobId(); String jobGroup = job.getJobGroup(); job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); int rows = jobMapper.updateJob(job); if(rows > 0){ scheduler.pauseJob(ScheduleUtils.getJobKey(jobId,jobGroup)); } return rows; } /** 恢復(fù)任務(wù) */ @Override @Transactional(rollbackFor = Exception.class) public int resumeJob(SysJob job)throws SchedulerException{ Long jobId = job.getJobId(); String jobGroup = job.getJobGroup(); job.setStatus(ScheduleConstants.Status.NORMAL.getValue()); int rows = jobMapper.updateJob(job); if(rows > 0){ scheduler.resumeJob(ScheduleUtils.getJobKey(jobId,jobGroup)); } return rows; } /** 刪除任務(wù)后,所對(duì)應(yīng)的trigger也將被刪除 */ @Override @Transactional(rollbackFor = Exception.class) public int deleteJob(SysJob job)throws SchedulerException{ Long jobId = job.getJobId(); String jobGroup = job.getJobGroup(); int rows = jobMapper.deleteJobById(jobId); if(rows > 0){ scheduler.deleteJob(ScheduleUtils.getJobKey(jobId,jobGroup)); } return rows; } /** 批量刪除調(diào)度信息 */ @Override @Transactional(rollbackFor = Exception.class) public void deleteJobByIds(Long[] jobIds)throws SchedulerException{ for(Long jobId:jobIds){ SysJob job = jobMapper.selectJobById(jobId); deleteJob(job); } } /** 任務(wù)調(diào)度狀態(tài)修改 */ @Override @Transactional(rollbackFor = Exception.class) public int changeStatus(SysJob job)throws SchedulerException{ int rows = 0; String status = job.getStatus(); if(ScheduleConstants.Status.NORMAL.getValue().equals(status)){ rows = resumeJob(job); }else if(ScheduleConstants.Status.PAUSE.getValue().equals(status)){ rows = pauseJob(job); } return rows; } /** 立即運(yùn)行任務(wù) */ @Override @Transactional(rollbackFor = Exception.class) public boolean run(SysJob job)throws SchedulerException{ boolean result = false; Long jobId = job.getJobId(); String jobGroup = job.getJobGroup(); SysJob properties = selectJobById(job.getJobId()); //參數(shù) JobDataMap dataMap = new JobDataMap();//quartz-2.3.2 dataMap.put(ScheduleConstants.TASK_PROPERTIES,properties); JobKey jobKey = ScheduleUtils.getJobKey(jobId,jobGroup); if(scheduler.checkExists(jobkey)){ result = true; scheduler.triggerJob(jobKey,dataMap); } return result; } /** 新增任務(wù) */ @Override @Transactional(rollbackFor = Exception.class) public int insertJob(SysJob job)throws SchedulerException, TaskException{ job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); int rows = jobMapper.insertJob(job); if(rows > 0){ ScheduleUtils.createScheduleJob(job); } return rows; } /** 更新任務(wù)的時(shí)間表達(dá)式 */ @Override @Transactional(rollbackFor = Exception.class) public int updateJob(SysJob job) throws SchedulerException, TaskException{ SysJob properties = selectJobById(job.getJobId()); int rows = jobMapper.updateJob(job); if(rows > 0){ updateSchedulerJob(job,properties.getJobGroup()); } return rows; } //更新任務(wù) public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException{ Long jobId = job.getJobId(); //判斷是否存在 JobKey jobKey = ScheduleUtils.getJobKey(jobId,jobGroup); if(scheduler.checkExists(jobKey)){ // 防止創(chuàng)建時(shí)存在數(shù)據(jù)問(wèn)題 先移除,然后在執(zhí)行創(chuàng)建操作 scheduler.deleteJob(jobKey); } ScheduleUtils.createScheduleJob(scheduler, job); } //校驗(yàn)cron表達(dá)式是否有效 @Override public boolean checkCronExpressionIsValid(String cronExpression){ return CronUtils.isValid(cronExpression) } }
定時(shí)任務(wù)調(diào)度表SysJob
public class SysJob extends BaseEntity{ private static final long serialVersionUID = 1L; /** 任務(wù)ID */ @Excel(name = "任務(wù)序號(hào)", cellType = ColumnType.NUMERIC) private Long jobId; /** 任務(wù)名稱(chēng) */ @Excel(name = "任務(wù)名稱(chēng)") private String jobName; /** 任務(wù)組名 */ @Excel(name = "任務(wù)組名") private String jobGroup; /** 調(diào)用目標(biāo)字符串 */ @Excel(name = "調(diào)用目標(biāo)字符串") private String invokeTarget; /** cron執(zhí)行表達(dá)式 */ @Excel(name = "執(zhí)行表達(dá)式 ") private String cronExpression; /** cron計(jì)劃策略 */ @Excel(name = "計(jì)劃策略 ", readConverterExp = "0=默認(rèn),1=立即觸發(fā)執(zhí)行,2=觸發(fā)一次執(zhí)行,3=不觸發(fā)立即執(zhí)行") private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT; /** 是否并發(fā)執(zhí)行(0允許 1禁止) */ @Excel(name = "并發(fā)執(zhí)行", readConverterExp = "0=允許,1=禁止") private String concurrent; /** 任務(wù)狀態(tài)(0正常 1暫停) */ @Excel(name = "任務(wù)狀態(tài)", readConverterExp = "0=正常,1=暫停") private String status; public Long getJobId() { return jobId; } public void setJobId(Long jobId) { this.jobId = jobId; } @NotBlank(message = "任務(wù)名稱(chēng)不能為空") @Size(min = 0, max = 64, message = "任務(wù)名稱(chēng)不能超過(guò)64個(gè)字符") public String getJobName() { return jobName; } public void setJobName(String jobName) { this.jobName = jobName; } public String getJobGroup() { return jobGroup; } public void setJobGroup(String jobGroup) { this.jobGroup = jobGroup; } @NotBlank(message = "調(diào)用目標(biāo)字符串不能為空") @Size(min = 0, max = 500, message = "調(diào)用目標(biāo)字符串長(zhǎng)度不能超過(guò)500個(gè)字符") public String getInvokeTarget() { return invokeTarget; } public void setInvokeTarget(String invokeTarget) { this.invokeTarget = invokeTarget; } @NotBlank(message = "Cron執(zhí)行表達(dá)式不能為空") @Size(min = 0, max = 255, message = "Cron執(zhí)行表達(dá)式不能超過(guò)255個(gè)字符") public String getCronExpression() { return cronExpression; } public void setCronExpression(String cronExpression) { this.cronExpression = cronExpression; } @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") public Date getNextValidTime() { if (StringUtils.isNotEmpty(cronExpression)) { return CronUtils.getNextExecution(cronExpression); } return null; } public String getMisfirePolicy() { return misfirePolicy; } public void setMisfirePolicy(String misfirePolicy) { this.misfirePolicy = misfirePolicy; } public String getConcurrent() { return concurrent; } public void setConcurrent(String concurrent) { this.concurrent = concurrent; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) .append("jobId", getJobId()) .append("jobName", getJobName()) .append("jobGroup", getJobGroup()) .append("cronExpression", getCronExpression()) .append("nextValidTime", getNextValidTime()) .append("misfirePolicy", getMisfirePolicy()) .append("concurrent", getConcurrent()) .append("status", getStatus()) .append("createBy", getCreateBy()) .append("createTime", getCreateTime()) .append("updateBy", getUpdateBy()) .append("updateTime", getUpdateTime()) .append("remark", getRemark()) .toString(); } }
/** * Entity基類(lèi) * * @author ruoyi */ public class BaseEntity implements Serializable { private static final long serialVersionUID = 1L; /** 搜索值 */ @JsonIgnore private String searchValue; /** 創(chuàng)建者 */ private String createBy; /** 創(chuàng)建時(shí)間 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; /** 更新者 */ private String updateBy; /** 更新時(shí)間 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date updateTime; /** 備注 */ private String remark; /** 請(qǐng)求參數(shù) */ @JsonInclude(JsonInclude.Include.NON_EMPTY) private Map<String, Object> params; public String getSearchValue() { return searchValue; } public void setSearchValue(String searchValue) { this.searchValue = searchValue; } public String getCreateBy() { return createBy; } public void setCreateBy(String createBy) { this.createBy = createBy; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public String getUpdateBy() { return updateBy; } public void setUpdateBy(String updateBy) { this.updateBy = updateBy; } public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } public Map<String, Object> getParams() { if (params == null) { params = new HashMap<>(); } return params; } public void setParams(Map<String, Object> params) { this.params = params; } }
CronUtils表達(dá)式工具
public class CronUtils{ /** * 返回一個(gè)布爾值代表一個(gè)給定的Cron表達(dá)式的有效性 * * @param cronExpression Cron表達(dá)式 * @return boolean 表達(dá)式是否有效 */ public static boolean isValid(String cronExpression) { return CronExpression.isValidExpression(cronExpression); } /** * 返回一個(gè)字符串值,表示該消息無(wú)效Cron表達(dá)式給出有效性 * * @param cronExpression Cron表達(dá)式 * @return String 無(wú)效時(shí)返回表達(dá)式錯(cuò)誤描述,如果有效返回null */ public static String getInvalidMessage(String cronExpression) { try { new CronExpression(cronExpression); return null; } catch (ParseException pe) { return pe.getMessage(); } } /** * 返回下一個(gè)執(zhí)行時(shí)間根據(jù)給定的Cron表達(dá)式 * * @param cronExpression Cron表達(dá)式 * @return Date 下次Cron表達(dá)式執(zhí)行時(shí)間 */ public static Date getNextExecution(String cronExpression) { try { CronExpression cron = new CronExpression(cronExpression); return cron.getNextValidTimeAfter(new Date(System.currentTimeMillis())); } catch (ParseException e) { throw new IllegalArgumentException(e.getMessage()); } } }
ScheduleUtils定時(shí)任務(wù)工具類(lèi)
public class ScheduleUtils{ /** * 得到quartz任務(wù)類(lèi) * * @param sysJob 執(zhí)行計(jì)劃 * @return 具體執(zhí)行任務(wù)類(lèi) */ private static Class<? extends Job> getQuartzJobClass(SysJob sysJob) { boolean isConcurrent = "0".equals(sysJob.getConcurrent()); return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class; } /** * 構(gòu)建任務(wù)觸發(fā)對(duì)象 */ public static TriggerKey getTriggerKey(Long jobId, String jobGroup) { return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); } /** * 構(gòu)建任務(wù)鍵對(duì)象 */ public static JobKey getJobKey(Long jobId, String jobGroup) { return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); } /** * 創(chuàng)建定時(shí)任務(wù) */ public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException { Class<? extends Job> jobClass = getQuartzJobClass(job); // 構(gòu)建job信息 Long jobId = job.getJobId(); String jobGroup = job.getJobGroup(); JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build(); // 表達(dá)式調(diào)度構(gòu)建器 CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); // 按新的cronExpression表達(dá)式構(gòu)建一個(gè)新的trigger CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup)) .withSchedule(cronScheduleBuilder).build(); // 放入?yún)?shù),運(yùn)行時(shí)的方法可以獲取 jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); // 判斷是否存在 if (scheduler.checkExists(getJobKey(jobId, jobGroup))) { // 防止創(chuàng)建時(shí)存在數(shù)據(jù)問(wèn)題 先移除,然后在執(zhí)行創(chuàng)建操作 scheduler.deleteJob(getJobKey(jobId, jobGroup)); } // 判斷任務(wù)是否過(guò)期 if (StringUtils.isNotNull(CronUtils.getNextExecution(job.getCronExpression()))) { // 執(zhí)行調(diào)度任務(wù) scheduler.scheduleJob(jobDetail, trigger); } // 暫停任務(wù) if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) { scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); } } /** * 設(shè)置定時(shí)任務(wù)策略 */ public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) throws TaskException { switch (job.getMisfirePolicy()) { case ScheduleConstants.MISFIRE_DEFAULT: return cb; case ScheduleConstants.MISFIRE_IGNORE_MISFIRES: return cb.withMisfireHandlingInstructionIgnoreMisfires(); case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED: return cb.withMisfireHandlingInstructionFireAndProceed(); case ScheduleConstants.MISFIRE_DO_NOTHING: return cb.withMisfireHandlingInstructionDoNothing(); default: throw new TaskException("The task misfire policy '" + job.getMisfirePolicy() + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR); } } /** * 檢查包名是否為白名單配置 * * @param invokeTarget 目標(biāo)字符串 * @return 結(jié)果 */ public static boolean whiteList(String invokeTarget) { String packageName = StringUtils.substringBefore(invokeTarget, "("); int count = StringUtils.countMatches(packageName, "."); if (count > 1) { return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR); } Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]); String beanPackageName = obj.getClass().getPackage().getName(); return StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_WHITELIST_STR) && !StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_ERROR_STR); } }
/** * 定時(shí)任務(wù)處理(允許并發(fā)執(zhí)行) * * @author ruoyi * */ public class QuartzJobExecution extends AbstractQuartzJob { @Override protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception { JobInvokeUtil.invokeMethod(sysJob); } }
/** * 定時(shí)任務(wù)處理(禁止并發(fā)執(zhí)行) * * @author ruoyi * */ @DisallowConcurrentExecution public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob { @Override protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception { JobInvokeUtil.invokeMethod(sysJob); } }
/** * 抽象quartz調(diào)用 * * @author ruoyi */ public abstract class AbstractQuartzJob implements Job { private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class); /** * 線(xiàn)程本地變量 */ private static ThreadLocal<Date> threadLocal = new ThreadLocal<>(); @Override public void execute(JobExecutionContext context) throws JobExecutionException { SysJob sysJob = new SysJob(); BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES)); try { before(context, sysJob); if (sysJob != null) { doExecute(context, sysJob); } after(context, sysJob, null); } catch (Exception e) { log.error("任務(wù)執(zhí)行異常 - :", e); after(context, sysJob, e); } } /** * 執(zhí)行前 * * @param context 工作執(zhí)行上下文對(duì)象 * @param sysJob 系統(tǒng)計(jì)劃任務(wù) */ protected void before(JobExecutionContext context, SysJob sysJob) { threadLocal.set(new Date()); } /** * 執(zhí)行后 * * @param context 工作執(zhí)行上下文對(duì)象 * @param sysJob 系統(tǒng)計(jì)劃任務(wù) */ protected void after(JobExecutionContext context, SysJob sysJob, Exception e) { Date startTime = threadLocal.get(); threadLocal.remove(); final SysJobLog sysJobLog = new SysJobLog(); sysJobLog.setJobName(sysJob.getJobName()); sysJobLog.setJobGroup(sysJob.getJobGroup()); sysJobLog.setInvokeTarget(sysJob.getInvokeTarget()); sysJobLog.setStartTime(startTime); sysJobLog.setStopTime(new Date()); long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime(); sysJobLog.setJobMessage(sysJobLog.getJobName() + " 總共耗時(shí):" + runMs + "毫秒"); if (e != null) { sysJobLog.setStatus("1"); String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000); sysJobLog.setExceptionInfo(errorMsg); } else { sysJobLog.setStatus("0"); } // 寫(xiě)入數(shù)據(jù)庫(kù)當(dāng)中 SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog); } /** * 執(zhí)行方法,由子類(lèi)重載 * * @param context 工作執(zhí)行上下文對(duì)象 * @param sysJob 系統(tǒng)計(jì)劃任務(wù) * @throws Exception 執(zhí)行過(guò)程中的異常 */ protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception; }
/** * 任務(wù)執(zhí)行工具 * * @author ruoyi */ public class JobInvokeUtil { /** * 執(zhí)行方法 * * @param sysJob 系統(tǒng)任務(wù) */ public static void invokeMethod(SysJob sysJob) throws Exception { String invokeTarget = sysJob.getInvokeTarget(); String beanName = getBeanName(invokeTarget); String methodName = getMethodName(invokeTarget); List<Object[]> methodParams = getMethodParams(invokeTarget); if (!isValidClassName(beanName)) { Object bean = SpringUtils.getBean(beanName); invokeMethod(bean, methodName, methodParams); } else { Object bean = Class.forName(beanName).getDeclaredConstructor().newInstance(); invokeMethod(bean, methodName, methodParams); } } /** * 調(diào)用任務(wù)方法 * * @param bean 目標(biāo)對(duì)象 * @param methodName 方法名稱(chēng) * @param methodParams 方法參數(shù) */ private static void invokeMethod(Object bean, String methodName, List<Object[]> methodParams) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0) { Method method = bean.getClass().getMethod(methodName, getMethodParamsType(methodParams)); method.invoke(bean, getMethodParamsValue(methodParams)); } else { Method method = bean.getClass().getMethod(methodName); method.invoke(bean); } } /** * 校驗(yàn)是否為為class包名 * * @param invokeTarget 名稱(chēng) * @return true是 false否 */ public static boolean isValidClassName(String invokeTarget) { return StringUtils.countMatches(invokeTarget, ".") > 1; } /** * 獲取bean名稱(chēng) * * @param invokeTarget 目標(biāo)字符串 * @return bean名稱(chēng) */ public static String getBeanName(String invokeTarget) { String beanName = StringUtils.substringBefore(invokeTarget, "("); return StringUtils.substringBeforeLast(beanName, "."); } /** * 獲取bean方法 * * @param invokeTarget 目標(biāo)字符串 * @return method方法 */ public static String getMethodName(String invokeTarget) { String methodName = StringUtils.substringBefore(invokeTarget, "("); return StringUtils.substringAfterLast(methodName, "."); } /** * 獲取method方法參數(shù)相關(guān)列表 * * @param invokeTarget 目標(biāo)字符串 * @return method方法相關(guān)參數(shù)列表 */ public static List<Object[]> getMethodParams(String invokeTarget) { String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")"); if (StringUtils.isEmpty(methodStr)) { return null; } String[] methodParams = methodStr.split(",(?=([^\"']*[\"'][^\"']*[\"'])*[^\"']*$)"); List<Object[]> classs = new LinkedList<>(); for (int i = 0; i < methodParams.length; i++) { String str = StringUtils.trimToEmpty(methodParams[i]); // String字符串類(lèi)型,以'或"開(kāi)頭 if (StringUtils.startsWithAny(str, "'", "\"")) { classs.add(new Object[] { StringUtils.substring(str, 1, str.length() - 1), String.class }); } // boolean布爾類(lèi)型,等于true或者false else if ("true".equalsIgnoreCase(str) || "false".equalsIgnoreCase(str)) { classs.add(new Object[] { Boolean.valueOf(str), Boolean.class }); } // long長(zhǎng)整形,以L結(jié)尾 else if (StringUtils.endsWith(str, "L")) { classs.add(new Object[] { Long.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Long.class }); } // double浮點(diǎn)類(lèi)型,以D結(jié)尾 else if (StringUtils.endsWith(str, "D")) { classs.add(new Object[] { Double.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Double.class }); } // 其他類(lèi)型歸類(lèi)為整形 else { classs.add(new Object[] { Integer.valueOf(str), Integer.class }); } } return classs; } /** * 獲取參數(shù)類(lèi)型 * * @param methodParams 參數(shù)相關(guān)列表 * @return 參數(shù)類(lèi)型列表 */ public static Class<?>[] getMethodParamsType(List<Object[]> methodParams) { Class<?>[] classs = new Class<?>[methodParams.size()]; int index = 0; for (Object[] os : methodParams) { classs[index] = (Class<?>) os[1]; index++; } return classs; } /** * 獲取參數(shù)值 * * @param methodParams 參數(shù)相關(guān)列表 * @return 參數(shù)值列表 */ public static Object[] getMethodParamsValue(List<Object[]> methodParams) { Object[] classs = new Object[methodParams.size()]; int index = 0; for (Object[] os : methodParams) { classs[index] = (Object) os[0]; index++; } return classs; } }
SpringUtils在非spring管理環(huán)境中獲取bean
/** * spring工具類(lèi) 方便在非spring管理環(huán)境中獲取bean * * @author ruoyi */ @Component public final class SpringUtils implements BeanFactoryPostProcessor { /** Spring應(yīng)用上下文環(huán)境 */ private static ConfigurableListableBeanFactory beanFactory; @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { SpringUtils.beanFactory = beanFactory; } /** * 獲取對(duì)象 * * @param name * @return Object 一個(gè)以所給名字注冊(cè)的bean的實(shí)例 * @throws org.springframework.beans.BeansException * */ @SuppressWarnings("unchecked") public static <T> T getBean(String name) throws BeansException { return (T) beanFactory.getBean(name); } /** * 獲取類(lèi)型為requiredType的對(duì)象 * * @param clz * @return * @throws org.springframework.beans.BeansException * */ public static <T> T getBean(Class<T> clz) throws BeansException { T result = (T) beanFactory.getBean(clz); return result; } /** * 如果BeanFactory包含一個(gè)與所給名稱(chēng)匹配的bean定義,則返回true * * @param name * @return boolean */ public static boolean containsBean(String name) { return beanFactory.containsBean(name); } /** * 判斷以給定名字注冊(cè)的bean定義是一個(gè)singleton還是一個(gè)prototype。 如果與給定名字相應(yīng)的bean定義沒(méi)有被找到,將會(huì)拋出一個(gè)異常(NoSuchBeanDefinitionException) * * @param name * @return boolean * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException * */ public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException { return beanFactory.isSingleton(name); } /** * @param name * @return Class 注冊(cè)對(duì)象的類(lèi)型 * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException * */ public static Class<?> getType(String name) throws NoSuchBeanDefinitionException { return beanFactory.getType(name); } /** * 如果給定的bean名字在bean定義中有別名,則返回這些別名 * * @param name * @return * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException * */ public static String[] getAliases(String name) throws NoSuchBeanDefinitionException { return beanFactory.getAliases(name); } /** * 獲取aop代理對(duì)象 * * @param invoker * @return */ @SuppressWarnings("unchecked") public static <T> T getAopProxy(T invoker) { return (T) AopContext.currentProxy(); } }
Bean工具類(lèi)
/** * Bean 工具類(lèi) * * @author ruoyi */ public class BeanUtils extends org.springframework.beans.BeanUtils { /** Bean方法名中屬性名開(kāi)始的下標(biāo) */ private static final int BEAN_METHOD_PROP_INDEX = 3; /** * 匹配getter方法的正則表達(dá)式 */ private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)"); /** * 匹配setter方法的正則表達(dá)式 */ private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)"); /** * Bean屬性復(fù)制工具方法。 * * @param dest 目標(biāo)對(duì)象 * @param src 源對(duì)象 */ public static void copyBeanProp(Object dest, Object src) { try { copyProperties(src, dest); } catch (Exception e) { e.printStackTrace(); } } /** * 獲取對(duì)象的setter方法。 * * @param obj 對(duì)象 * @return 對(duì)象的setter方法列表 */ public static List<Method> getSetterMethods(Object obj) { // setter方法列表 List<Method> setterMethods = new ArrayList<Method>(); // 獲取所有方法 Method[] methods = obj.getClass().getMethods(); // 查找setter方法 for (Method method : methods) { Matcher m = SET_PATTERN.matcher(method.getName()); if (m.matches() && (method.getParameterTypes().length == 1)) { setterMethods.add(method); } } // 返回setter方法列表 return setterMethods; } /** * 獲取對(duì)象的getter方法。 * * @param obj 對(duì)象 * @return 對(duì)象的getter方法列表 */ public static List<Method> getGetterMethods(Object obj) { // getter方法列表 List<Method> getterMethods = new ArrayList<Method>(); // 獲取所有方法 Method[] methods = obj.getClass().getMethods(); // 查找getter方法 for (Method method : methods) { Matcher m = GET_PATTERN.matcher(method.getName()); if (m.matches() && (method.getParameterTypes().length == 0)) { getterMethods.add(method); } } // 返回getter方法列表 return getterMethods; } /** * 檢查Bean方法名中的屬性名是否相等。<br> * 如getName()和setName()屬性名一樣,getName()和setAge()屬性名不一樣。 * * @param m1 方法名1 * @param m2 方法名2 * @return 屬性名一樣返回true,否則返回false */ public static boolean isMethodPropEquals(String m1, String m2) { return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX)); } }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java使用建造者模式實(shí)現(xiàn)辦理手機(jī)套餐功能詳解
這篇文章主要介紹了Java使用建造者模式實(shí)現(xiàn)辦理手機(jī)套餐功能,較為詳細(xì)的描述了建造者模式的概念、原理并結(jié)合實(shí)例形式分析了Java使用建造者模式實(shí)現(xiàn)的辦理手機(jī)套餐功能具體步驟與相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2018-05-05java實(shí)現(xiàn)雙色球抽獎(jiǎng)算法
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)雙色球抽獎(jiǎng)算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05Java中的==和equals()區(qū)別小結(jié)
在Java編程中,理解==操作符和equals()方法的區(qū)別是至關(guān)重要的,本文主要介紹了Java中的==和equals()區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08spring security實(shí)現(xiàn)下次自動(dòng)登錄功能過(guò)程解析
這篇文章主要介紹了spring security實(shí)現(xiàn)記住我下次自動(dòng)登錄功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11Java實(shí)現(xiàn)大數(shù)運(yùn)算的實(shí)例代碼
這篇文章主要介紹了Java實(shí)現(xiàn)大數(shù)運(yùn)算的實(shí)例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06Mybatis 實(shí)現(xiàn)一個(gè)搜索框?qū)Χ鄠€(gè)字段進(jìn)行模糊查詢(xún)
這篇文章主要介紹了Mybatis 實(shí)現(xiàn)一個(gè)搜索框?qū)Χ鄠€(gè)字段進(jìn)行模糊查詢(xún),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01Java實(shí)現(xiàn)計(jì)算器設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)計(jì)算器設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07Springboot使用SPI注冊(cè)bean到spring容器的示例代碼
這篇文章主要介紹了Springboot使用SPI注冊(cè)bean到spring容器,主要包括mydriver接口,mysqldriver實(shí)現(xiàn)過(guò)程,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10