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

SpringBoot?整合?Quartz?定時(shí)任務(wù)框架詳解

 更新時(shí)間:2022年08月16日 09:12:32   作者:寧在春  
這篇文章主要介紹了SpringBoot整合Quartz定時(shí)任務(wù)框架詳解,Quartz是一個(gè)完全由Java編寫(xiě)的開(kāi)源作業(yè)調(diào)度框架,為在Java應(yīng)用程序中進(jìn)行作業(yè)調(diào)度提供了簡(jiǎn)單卻強(qiáng)大的機(jī)制

前言

在選擇技術(shù)棧之前,一定要先明確一件事情,你真的需要用它嗎?還有其他方式可以使用嗎?

相比其他技術(shù)技術(shù),優(yōu)點(diǎn)在哪里呢?使用了之后的利與弊等等。

寫(xiě)這個(gè)主要是因?yàn)橐恢毕雽?xiě)一下定時(shí)任務(wù)這個(gè)主題,這個(gè)算是寫(xiě)那篇文前期的鋪墊和基礎(chǔ)吧~

本文沒(méi)有聊到 Java其他的實(shí)現(xiàn)定時(shí)任務(wù)的方法啥的~,只是對(duì)使用 Quartz 做了一個(gè)小實(shí)踐

一、簡(jiǎn)單聊一聊 Quartz

Quartz 是一個(gè)完全由 Java 編寫(xiě)的開(kāi)源作業(yè)調(diào)度框架,為在 Java 應(yīng)用程序中進(jìn)行作業(yè)調(diào)度提供了簡(jiǎn)單卻強(qiáng)大的機(jī)制。

Quartz 其實(shí)就是通過(guò)一個(gè)調(diào)度線程不斷的掃描數(shù)據(jù)庫(kù)中的數(shù)據(jù)來(lái)獲取到那些已經(jīng)到點(diǎn)要觸發(fā)的任務(wù),然后調(diào)度執(zhí)行它的。這個(gè)線程就是 QuartzSchedulerThread類。其run方法中就是quartz的調(diào)度邏輯。

另外,這是一個(gè)Demo,木有考慮并發(fā)、多任務(wù)執(zhí)行等等狀態(tài)的發(fā)生及處理情況,見(jiàn)諒。

1.1、Quartz 概念

Quartz 的幾個(gè)核心概念:

  • Job

表示一個(gè)工作,要執(zhí)行的具體內(nèi)容。此接口中只有一個(gè)方法

?void execute(JobExecutionContext context) 

JobDetail 表示一個(gè)具體的可執(zhí)行的調(diào)度程序,Job 是這個(gè)可執(zhí)行程調(diào)度程序所要執(zhí)行的內(nèi)容,另外 JobDetail 還包含了這個(gè)任務(wù)調(diào)度的方案和策略。

Trigger 代表一個(gè)調(diào)度參數(shù)的配置,什么時(shí)候去調(diào)。

Scheduler 代表一個(gè)調(diào)度容器,一個(gè)調(diào)度容器中可以注冊(cè)多個(gè) JobDetail 和 Trigger。當(dāng) Trigger 與 JobDetail 組合,就可以被 Scheduler 容器調(diào)度了。

二、SpringBoot 使用 Quartz

2.1、基本步驟

基本步驟就那些,這篇也不是高大上講原理和流程之類的,就是偏向?qū)嵅?,可能一些地方在代碼中含有注釋,就不再貼說(shuō)明了~

基本:JDK 8、SpringBoot、MybatisPlus、Quartz

創(chuàng)建一個(gè) SpringBoot 項(xiàng)目

導(dǎo)入相關(guān)依賴~

?<parent>
? ? ?<groupId>org.springframework.boot</groupId>
? ? ?<artifactId>spring-boot-starter-parent</artifactId>
? ? ?<version>2.5.2</version>
? ? ?<relativePath/>
?</parent>

?<properties>
? ? ?<java.version>1.8</java.version>
? ? ?<maven.compiler.source>8</maven.compiler.source>
? ? ?<maven.compiler.target>8</maven.compiler.target>
?</properties>

?<dependencies>
? ? ?<dependency>
? ? ? ? ?<groupId>org.springframework.boot</groupId>
? ? ? ? ?<artifactId>spring-boot-starter-web</artifactId>
? ? ?</dependency>
? ? ?<dependency>
? ? ? ? ?<groupId>org.springframework.boot</groupId>
? ? ? ? ?<artifactId>spring-boot-starter-quartz</artifactId>
? ? ?</dependency>
? ? ?<dependency>
? ? ? ? ?<groupId>org.projectlombok</groupId>
? ? ? ? ?<artifactId>lombok</artifactId>
? ? ?</dependency>
? ? ?<dependency>
? ? ? ? ?<groupId>mysql</groupId>
? ? ? ? ?<artifactId>mysql-connector-java</artifactId>
? ? ?</dependency>
? ? ?<dependency>
? ? ? ? ?<groupId>com.baomidou</groupId>
? ? ? ? ?<artifactId>mybatis-plus-boot-starter</artifactId>
? ? ? ? ?<version>3.4.1</version>
? ? ?</dependency>

? ? ?<dependency>
? ? ? ? ?<groupId>cn.hutool</groupId>
? ? ? ? ?<artifactId>hutool-all</artifactId>
? ? ? ? ?<version>5.1.4</version>
? ? ?</dependency>
? ? ?<dependency>
? ? ? ? ?<groupId>com.alibaba</groupId>
? ? ? ? ?<artifactId>fastjson</artifactId>
? ? ? ? ?<version>1.2.76</version>
? ? ?</dependency>
?</dependencies>

項(xiàng)目結(jié)構(gòu):

2.2、執(zhí)行 Quartz 需要的SQL文件

找到 quartz 需要的 sql 文件,在數(shù)據(jù)庫(kù)中執(zhí)行,這也是Quartz持久化的基礎(chǔ)~

 往下滑,找到你需要的sql文件即可。

執(zhí)行完的結(jié)果:

在此基礎(chǔ)上,我們?cè)兕~外增加一張表,與我們可能有業(yè)務(wù)關(guān)聯(lián)的信息整合,這啥啥允許為空,是方便我寫(xiě)測(cè)試~,并非正例

DROP TABLE IF EXISTS `sys_quartz_job`;
CREATE TABLE `sys_quartz_job`  (
  `id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `create_by` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '創(chuàng)建人',
  `create_time` datetime NULL DEFAULT NULL COMMENT '創(chuàng)建時(shí)間',
  `del_flag` int(1) UNSIGNED ZEROFILL NULL DEFAULT 0 COMMENT '刪除狀態(tài)',
  `update_by` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '修改人',
  `update_time` datetime NULL DEFAULT NULL COMMENT '修改時(shí)間',
  `job_class_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '任務(wù)類名',
  `cron_expression` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'cron表達(dá)式',
  `parameter` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '參數(shù)',
  `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '描述',
  `status` int(1) NULL DEFAULT NULL COMMENT '狀態(tài) 0正常 -1停止',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;

2.3、Controller

我們直接從controller說(shuō)起吧,從上往下開(kāi)發(fā)。

其實(shí)一旦牽扯到表的操作,我們無(wú)疑就是crud四件事。

?/**
? * @Description: 定時(shí)任務(wù)在線管理
? * @author nzc
? */
?@RestController
?@RequestMapping("/quartzJob")
?@Slf4j
?public class QuartzJobController {

?    @Autowired
?    private IQuartzJobService quartzJobService;
?    @Autowired
?    private Scheduler scheduler;


?    @RequestMapping(value = "/list", method = RequestMethod.GET)
?    public Result<?> queryPageList(QuartzJob quartzJob, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
?                                 ? @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
?        Page<QuartzJob> page = new Page<QuartzJob>(pageNo, pageSize);
?        IPage<QuartzJob> pageList = quartzJobService.page(page);
? ? ? ? ?return Result.ok(pageList);

?    }

?    @RequestMapping(value = "/add", method = RequestMethod.POST)
?    public Result<?> add(@RequestBody QuartzJob quartzJob) {
List<QuartzJob> list = quartzJobService.list(new QueryWrapper<QuartzJob>().eq("job_class_name", quartzJob.getJobClassName()));
?        if (list != null && list.size() > 0) {
?            return Result.error("該定時(shí)任務(wù)類名已存在");
?        }
?        quartzJobService.saveAndScheduleJob(quartzJob);
?        return Result.ok("創(chuàng)建定時(shí)任務(wù)成功");
?    }

?    @RequestMapping(value = "/edit", method = RequestMethod.PUT)
?    public Result<?> eidt(@RequestBody QuartzJob quartzJob) {
?        try {
?            quartzJobService.editAndScheduleJob(quartzJob);
?        } catch (SchedulerException e) {
?            log.error(e.getMessage(),e);
?            return Result.error("更新定時(shí)任務(wù)失敗!");
?        }
?     ? ?return Result.ok("更新定時(shí)任務(wù)成功!");
?    }

?    @RequestMapping(value = "/delete", method = RequestMethod.DELETE)
?    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
?        QuartzJob quartzJob = quartzJobService.getById(id);
?        if (quartzJob == null) {
?            return Result.error("未找到對(duì)應(yīng)實(shí)體");
?        }
?        quartzJobService.deleteAndStopJob(quartzJob);
? ? ? ? ?return Result.ok("刪除成功!");

?    }

?    @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
?    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
?        if (ids == null || "".equals(ids.trim())) {
?            return Result.error("參數(shù)不識(shí)別!");
?        }
?        for (String id : Arrays.asList(ids.split(","))) {
?            QuartzJob job = quartzJobService.getById(id);
?            quartzJobService.deleteAndStopJob(job);
?        }
? ? ? ? ?return Result.ok("刪除定時(shí)任務(wù)成功!");
?    }

?    /**
?     * 暫停定時(shí)任務(wù)
?     * @param jobClassName
?     */
?    @GetMapping(value = "/pause")
?    public Result<Object> pauseJob(@RequestParam(name = "jobClassName", required = true) String jobClassName) {
?        QuartzJob job = null;
?        try {
?            job = quartzJobService.getOne(new LambdaQueryWrapper<QuartzJob>().eq(QuartzJob::getJobClassName, jobClassName));
?            if (job == null) {
?                return Result.error("定時(shí)任務(wù)不存在!");
?            }
?            scheduler.pauseJob(JobKey.jobKey(jobClassName.trim()));
?        } catch (SchedulerException e) {
?            throw new MyException("暫停定時(shí)任務(wù)失敗");
?        }
?        job.setStatus(CommonConstant.STATUS_DISABLE);
?        quartzJobService.updateById(job);
?        return Result.ok("暫停定時(shí)任務(wù)成功");
?    }

?    /**
?     * 恢復(fù)定時(shí)任務(wù)
?     * @param jobClassName
?     */
?    @GetMapping(value = "/resume")
?    public Result<Object> resumeJob(@RequestParam(name = "jobClassName", required = true) String jobClassName) {
?        QuartzJob job = quartzJobService.getOne(new LambdaQueryWrapper<QuartzJob>().eq(QuartzJob::getJobClassName, jobClassName));
?        if (job == null) {
?            return Result.error("定時(shí)任務(wù)不存在!");
?        }
?        quartzJobService.resumeJob(job);
?        //scheduler.resumeJob(JobKey.jobKey(job.getJobClassName().trim()));
?        return Result.ok("恢復(fù)定時(shí)任務(wù)成功");
?    }
?    /** 通過(guò)id查詢*/
?    @RequestMapping(value = "/queryById", method = RequestMethod.GET)
?    public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
?        QuartzJob quartzJob = quartzJobService.getById(id);
? ? ? ? ?return Result.ok(quartzJob);
?    }
?}

2.4、Service 劃重點(diǎn)

?public interface IQuartzJobService extends IService<QuartzJob> {
?    boolean saveAndScheduleJob(QuartzJob quartzJob);
?    boolean editAndScheduleJob(QuartzJob quartzJob) throws SchedulerException;
?    boolean deleteAndStopJob(QuartzJob quartzJob);
?    boolean resumeJob(QuartzJob quartzJob);
?}

其中最主要的實(shí)現(xiàn)都是在這里:

?@Slf4j
?@Service
?public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob> implements IQuartzJobService {

?    @Autowired
?    private QuartzJobMapper quartzJobMapper;

?    @Autowired
?    private Scheduler scheduler;


?    /**保存&啟動(dòng)定時(shí)任務(wù)*/
?    @Override
?    public boolean saveAndScheduleJob(QuartzJob quartzJob) {
?        if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
?            // 定時(shí)器添加
?            this.schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
?        }
?        // DB設(shè)置修改
?        return this.save(quartzJob);
?    }
?    /**恢復(fù)定時(shí)任務(wù) */
?    @Override
?    public boolean resumeJob(QuartzJob quartzJob) {
?        schedulerDelete(quartzJob.getJobClassName().trim());
?        schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
?        quartzJob.setStatus(CommonConstant.STATUS_NORMAL);
?        return this.updateById(quartzJob);
?    }

?    /**編輯&啟停定時(shí)任務(wù) @throws SchedulerException */
?    @Override
?    public boolean editAndScheduleJob(QuartzJob quartzJob) throws SchedulerException {
?        if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
?            schedulerDelete(quartzJob.getJobClassName().trim());
?            schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
?        }else{
?            scheduler.pauseJob(JobKey.jobKey(quartzJob.getJobClassName().trim()));
?        }
?        return this.updateById(quartzJob);
?    }

?    /**刪除&停止刪除定時(shí)任務(wù)*/
?    @Override
?    public boolean deleteAndStopJob(QuartzJob job) {
?        schedulerDelete(job.getJobClassName().trim());
?        return this.removeById(job.getId());
?    }

?    /** 添加定時(shí)任務(wù)*/
?    private void schedulerAdd(String jobClassName, String cronExpression, String parameter) {
?        try {
?            // 啟動(dòng)調(diào)度器
?            scheduler.start();

?            // 構(gòu)建job信息
?            JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobClassName).usingJobData("parameter", parameter).build();

?            // 表達(dá)式調(diào)度構(gòu)建器(即任務(wù)執(zhí)行的時(shí)間)
?            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);

?            // 按新的cronExpression表達(dá)式構(gòu)建一個(gè)新的trigger
?            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName).withSchedule(scheduleBuilder).build();

?            scheduler.scheduleJob(jobDetail, trigger);
?        } catch (SchedulerException e) {
?            throw new MyException("創(chuàng)建定時(shí)任務(wù)失敗", e);
?        } catch (RuntimeException e) {
?            throw new MyException(e.getMessage(), e);
?        }catch (Exception e) {
?            throw new MyException("后臺(tái)找不到該類名:" + jobClassName, e);
?        }
?    }

?    /** 刪除定時(shí)任務(wù)*/
?    private void schedulerDelete(String jobClassName) {
?        try {
?            /*使用給定的鍵暫停Trigger 。*/
?            scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName));
?            /*從調(diào)度程序中刪除指示的Trigger */
?            scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName));
?            /*從 Scheduler 中刪除已識(shí)別的Job - 以及任何關(guān)聯(lián)的Trigger */
?            scheduler.deleteJob(JobKey.jobKey(jobClassName));
?        } catch (Exception e) {
?            log.error(e.getMessage(), e);
?            throw new MyException("刪除定時(shí)任務(wù)失敗");
?        }
?    }
?    private static Job getClass(String classname) throws Exception {
?        Class<?> class1 = Class.forName(classname);
?        return (Job) class1.newInstance();
?    }
?}
?@Mapper
?public interface QuartzJobMapper extends BaseMapper<QuartzJob> {

?}

2.5、實(shí)體類

?@Data
?@TableName("sys_quartz_job")
?public class QuartzJob implements Serializable {

? ?  @TableId(type = IdType.ID_WORKER_STR)
? ?  private String id;

? ?  private String createBy;

? ?  private String updateBy;

? ?  /**任務(wù)類名*/
? ?  private String jobClassName;

? ?  /** cron表達(dá)式 */
? ?  private String cronExpression;
? ?  /**  參數(shù)*/
? ?  private String parameter;

? ?  private String description;
? ?  /** 狀態(tài) 0正常 -1停止*/
? ?  private Integer status;

? ?  @TableLogic
? ?  private Integer delFlag;
? ?  @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
? ?  @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
? ?  @TableField(fill = FieldFill.INSERT)
?   private Date createTime;
? ?  @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
? ?  @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
? ?  @TableField(fill = FieldFill.INSERT_UPDATE)
? ?  private Date updateTime;
?}

另外在這里順帶補(bǔ)充一下,本項(xiàng)目在yml中配置quartz,如下:

spring:
  ## quartz定時(shí)任務(wù),采用數(shù)據(jù)庫(kù)方式
  quartz:
    job-store-type: jdbc

2.6、簡(jiǎn)單的 Job 案例

如果調(diào)度器要執(zhí)行任務(wù),首先得要有一個(gè)任務(wù)相關(guān)滴類。

寫(xiě)了兩個(gè)平常的案例,一個(gè)是不帶參數(shù)的,一個(gè)是帶參數(shù)的。

/**
 * 不帶參的簡(jiǎn)單定時(shí)任務(wù)
 * @Author nzc
 */
@Slf4j
public class SampleJob implements Job {

	@Override
	public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

		log.info(String.format("Ning zaichun的 普通定時(shí)任務(wù) SampleJob !  時(shí)間:" + new Date()));
	}
}

帶參數(shù)的:

?/**
? * 帶參數(shù)的簡(jiǎn)單的定時(shí)任務(wù)
? * @Author nzc
? */
?@Slf4j
?public class SampleParamJob implements Job {

?    /**
?     * 若參數(shù)變量名修改 QuartzJobController中也需對(duì)應(yīng)修改
?     */
?    private String parameter;

?    public void setParameter(String parameter) {
?        this.parameter = parameter;
?    }
?    @Override
?    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
?        log.info(String.format("welcome %s! Jeecg-Boot 帶參數(shù)定時(shí)任務(wù) SampleParamJob ! ? 時(shí)間:" + LocalDateTime.now(), this.parameter));
?    }
?}

2.7、那么該如何使用呢?

啟動(dòng)項(xiàng)目,讓我們拿起來(lái)postman來(lái)測(cè)試吧,康康該如何使用,數(shù)據(jù)表在使用的時(shí)候,又有怎么樣的變化~

我們直接來(lái)測(cè)試添加定時(shí)任務(wù)的接口,先來(lái)個(gè)不用參數(shù)的吧

?{
? ? ?"createBy": "nzc",
? ? ?"jobClassName": "com.nzc.quartz.job.SampleJob",
? ? ?"cronExpression": "0/10 * * * * ? ",
? ? ?"description": "每十秒執(zhí)行一次",
? ? ?"status": "0"
?}

添加完之后就已經(jīng)在執(zhí)行了。 

此時(shí)我們將項(xiàng)目停止,重新啟動(dòng)~

調(diào)度器也會(huì)主動(dòng)去檢測(cè)任務(wù)信息,如果有,就會(huì)開(kāi)始執(zhí)行。

我們?cè)賮?lái)測(cè)測(cè)帶有參數(shù)的 

也是可以成功的,并且也是按照我們?cè)O(shè)定的時(shí)間執(zhí)行的

其他的接口也是同樣如此,根據(jù)接口的設(shè)定,將參數(shù)傳入即可

到此這篇關(guān)于SpringBoot 整合 Quartz 定時(shí)任務(wù)框架詳解的文章就介紹到這了,更多相關(guān)SpringBoot 整合 Quartz 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中@Autowired和@Resource區(qū)別

    Java中@Autowired和@Resource區(qū)別

    本文主要介紹了Java中@Autowired和@Resource區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Java中的CopyOnWriteArrayList詳解

    Java中的CopyOnWriteArrayList詳解

    這篇文章主要介紹了Java中的CopyOnWriteArrayList詳解,ArrayList單線程下是安全的 但是多線程下存在不安全的問(wèn)題,多線程下是不安全的,需要的朋友可以參考下
    2023-12-12
  • 一些java二進(jìn)制的相關(guān)基礎(chǔ)知識(shí)

    一些java二進(jìn)制的相關(guān)基礎(chǔ)知識(shí)

    這篇文章主要介紹了一些java二進(jìn)制的相關(guān)基礎(chǔ)知識(shí),在Java語(yǔ)言中byte代表最小計(jì)量單位,byte由8位2進(jìn)制數(shù)組成。,需要的朋友可以參考下
    2019-06-06
  • 解決SpringBoot運(yùn)行報(bào)錯(cuò):找不到或無(wú)法加載主類的問(wèn)題

    解決SpringBoot運(yùn)行報(bào)錯(cuò):找不到或無(wú)法加載主類的問(wèn)題

    這篇文章主要介紹了解決SpringBoot運(yùn)行報(bào)錯(cuò):找不到或無(wú)法加載主類的問(wèn)題,具有很好的參考價(jià)值,對(duì)大家的學(xué)習(xí)或工作有一定的參考價(jià)值,需要的朋友可以參考下
    2023-09-09
  • 使用Jenkins配置Git+Maven的自動(dòng)化構(gòu)建的方法

    使用Jenkins配置Git+Maven的自動(dòng)化構(gòu)建的方法

    這篇文章主要介紹了使用Jenkins配置Git+Maven的自動(dòng)化構(gòu)建的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • Java?空和null的區(qū)別

    Java?空和null的區(qū)別

    本文主要介紹了Java?空和null的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-04-04
  • Java分支結(jié)構(gòu)和循環(huán)結(jié)構(gòu)原理與用法詳解

    Java分支結(jié)構(gòu)和循環(huán)結(jié)構(gòu)原理與用法詳解

    這篇文章主要介紹了Java分支結(jié)構(gòu)和循環(huán)結(jié)構(gòu)原理與用法,結(jié)合實(shí)例形式分析了java分支結(jié)構(gòu)、循環(huán)結(jié)構(gòu)、跳轉(zhuǎn)語(yǔ)句等相關(guān)概念、原理、使用技巧與操作注意事項(xiàng),需要的朋友可以參考下
    2020-02-02
  • Java使用Apache POI操作Excel詳解

    Java使用Apache POI操作Excel詳解

    在Java中操作Excel是日常工作中經(jīng)常遇到的問(wèn)題,而Apache Poi是一種流行且廣泛使用的方式,它提供了各種庫(kù)和工具,所以本文就來(lái)詳細(xì)如何使用Apache Poi來(lái)進(jìn)行Excel文件操作吧
    2023-06-06
  • Spring boot 無(wú)法注入service問(wèn)題

    Spring boot 無(wú)法注入service問(wèn)題

    這篇文章主要介紹了Spring boot 無(wú)法注入service問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • SpringCloud Eureka自我保護(hù)機(jī)制原理解析

    SpringCloud Eureka自我保護(hù)機(jī)制原理解析

    這篇文章主要介紹了SpringCloud Eureka自我保護(hù)機(jī)制原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02

最新評(píng)論