欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Scheduler定時(shí)任務(wù)調(diào)度詳解

 更新時(shí)間:2025年01月14日 14:52:14   作者:A塵埃  
文章介紹了SysJobServiceImpl類(lèi)中定時(shí)任務(wù)調(diào)度的相關(guān)方法,包括清除、檢查存在性、創(chuàng)建、暫停、恢復(fù)、刪除任務(wù),以及觸發(fā)任務(wù),并提到了JobKey、CronUtils、ScheduleUtils、SpringUtils等工具類(lèi)的使用,適用于Spring管理環(huán)境

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)文章

  • SpringBoot之Banner的使用示例

    SpringBoot之Banner的使用示例

    本篇文章主要介紹了SpringBoot之Banner的使用示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • Java使用建造者模式實(shí)現(xiàn)辦理手機(jī)套餐功能詳解

    Java使用建造者模式實(shí)現(xiàn)辦理手機(jī)套餐功能詳解

    這篇文章主要介紹了Java使用建造者模式實(shí)現(xiàn)辦理手機(jī)套餐功能,較為詳細(xì)的描述了建造者模式的概念、原理并結(jié)合實(shí)例形式分析了Java使用建造者模式實(shí)現(xiàn)的辦理手機(jī)套餐功能具體步驟與相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2018-05-05
  • HashMap容量和負(fù)載因子使用說(shuō)明

    HashMap容量和負(fù)載因子使用說(shuō)明

    這篇文章主要介紹了HashMap容量和負(fù)載因子使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • java實(shí)現(xiàn)雙色球抽獎(jiǎng)算法

    java實(shí)現(xiàn)雙色球抽獎(jiǎng)算法

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)雙色球抽獎(jiǎng)算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • Java中的==和equals()區(qū)別小結(jié)

    Java中的==和equals()區(qū)別小結(jié)

    在Java編程中,理解==操作符和equals()方法的區(qū)別是至關(guān)重要的,本文主要介紹了Java中的==和equals()區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-08-08
  • spring security實(shí)現(xiàn)下次自動(dòng)登錄功能過(guò)程解析

    spring security實(shí)現(xiàn)下次自動(dòng)登錄功能過(guò)程解析

    這篇文章主要介紹了spring security實(shí)現(xiàn)記住我下次自動(dòng)登錄功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Java實(shí)現(xiàn)大數(shù)運(yùn)算的實(shí)例代碼

    Java實(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-06
  • Mybatis 實(shí)現(xiàn)一個(gè)搜索框?qū)Χ鄠€(gè)字段進(jìn)行模糊查詢(xún)

    Mybatis 實(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-01
  • Java實(shí)現(xiàn)計(jì)算器設(shè)計(jì)

    Java實(shí)現(xiàn)計(jì)算器設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)計(jì)算器設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Springboot使用SPI注冊(cè)bean到spring容器的示例代碼

    Springboot使用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

最新評(píng)論