最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot實(shí)現(xiàn)輕量級動態(tài)定時(shí)任務(wù)管控及組件化的操作步驟

 更新時(shí)間:2024年11月23日 09:20:13   作者:糖拌西紅柿  
文章介紹了一種在SpringBoot中實(shí)現(xiàn)動態(tài)定時(shí)任務(wù)的解決方案,基于COLA架構(gòu)理論,封裝到了組件層,該組件支持類級別和方法級別的定時(shí)任務(wù)注冊,并提供了易用性和擴(kuò)展性,組件使用Maven形式引入,并且可以通過YAML配置文件進(jìn)行設(shè)置,感興趣的朋友一起看看吧

關(guān)于動態(tài)定時(shí)任務(wù)

關(guān)于在SpringBoot中使用定時(shí)任務(wù),大部分都是直接使用SpringBoot的@Scheduled注解,如下:

@Component
public class TestTask
{
    @Scheduled(cron="0/5 * *  * * ? ")   //每5秒執(zhí)行一次
    public void execute(){
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
        log.info("任務(wù)執(zhí)行" + df.format(new Date()));
    }
}

或者或者使用第三方的工具,例如XXL-Job等。就XXL-Job而言,如果說是大型項(xiàng)目,硬件資源和項(xiàng)目環(huán)境都具備,XXL-Job確實(shí)是最佳的選擇,可是對于項(xiàng)目體量不大,又不想過多的引入插件;使用XXL-Job多少有點(diǎn)“殺雞用牛刀”的意思;

之所以這樣說,是因?yàn)樵赟pringBoot中集成使用XXL-Job的步驟如下:

  • 引入依賴,配置執(zhí)行器Bean
  • 在自己項(xiàng)目中編寫定時(shí)任務(wù)代碼
  • 部署XXL-Job
  • 登錄XXL-Job調(diào)度中心的 Web 控制臺,創(chuàng)建一個(gè)新的任務(wù),選擇剛才配置的執(zhí)行器和任務(wù)處理器,設(shè)置好觸發(fā)條件(如 Cron 表達(dá)式)和其他選項(xiàng)后保存
  • 生產(chǎn)環(huán)境下,還要把配置好任務(wù)的XXL-Job和項(xiàng)目一起打包
@Component
public class SampleXxlJob {
    @XxlJob("sampleJobHandler")
    public void sampleJobHandler() throws Exception {
        // 業(yè)務(wù)邏輯
        System.out.println("Hello XXL-JOB!");
    }
}

這一套步驟在中小型項(xiàng)目中,明顯成本大于效果,而使用XXL-Job無非就是想動態(tài)的去管理定時(shí)任務(wù),可以在運(yùn)行狀態(tài)下隨意的執(zhí)行、中斷、調(diào)整執(zhí)行周期、查看運(yùn)行結(jié)果,而不是像基于@Scheduled注解實(shí)現(xiàn)后,無法改變。

所以,這里就基于SpringBoot實(shí)現(xiàn)動態(tài)調(diào)度定時(shí)任務(wù),之前針對這個(gè)問題,我寫過一篇CSDN文章(連接放在下方),最近博主將相關(guān)的代碼進(jìn)行了匯總,并且在易用性和擴(kuò)展性上進(jìn)行了加強(qiáng),基于COLA架構(gòu)理論,封裝到了組件層

這次加強(qiáng)主要包括:

  • 剝離了任務(wù)的持久化,使其依賴更簡潔,真正以starter的形式開箱即用
  • 擴(kuò)展了方法級的定時(shí)任務(wù)注冊,能夠像xxl-job一樣,一個(gè)注解搞定動態(tài)定時(shí)任務(wù)的注冊及管理

2|0動態(tài)定時(shí)任務(wù)實(shí)現(xiàn)思路

關(guān)于動態(tài)定時(shí)任務(wù)的核心思路是反射+定時(shí)任務(wù)模板,這兩部分的核心框架不變,相關(guān)內(nèi)容可以回顧我之前的博客:

輕量級動態(tài)定時(shí)任務(wù)調(diào)度

這里主要是針對強(qiáng)化的第二點(diǎn)進(jìn)行思路解釋,第二點(diǎn)的強(qiáng)化是加入了類掃描機(jī)制,通過掃描,實(shí)現(xiàn)了自動注冊,規(guī)避了之前每新增一個(gè)定時(shí)任務(wù)都必須得預(yù)制SQL的步驟:

類級別定時(shí)任務(wù)實(shí)現(xiàn)思路:在原模板模式的基礎(chǔ)下,基于AbstractBaseCronTask類自定義的定時(shí)任務(wù)子類作為類級別定時(shí)任務(wù),即一個(gè)類為一個(gè)定時(shí)任務(wù),初始時(shí)由包掃描所有的子類,并使用反射將其實(shí)例化,逐一加入到進(jìn)程管理中,并激活定時(shí)調(diào)度。

基于@MethodJob的方法級別任務(wù)實(shí)現(xiàn)思路:以 AbstractBaseCronTask類為基礎(chǔ),定義一個(gè)固定的子類BaseMethodLevelTask,并在其內(nèi)部限定任務(wù)的執(zhí)行方式掃描所有標(biāo)注了@MethodJob的方法及其所屬的Bean,連同Bean及方法的反射類作為構(gòu)造函數(shù),生成BaseMethodLevelTask對象,因?yàn)锽aseMethodLevelTask也是AbstractBaseCronTask的子類,則可以以類級別定時(shí)任務(wù)的方式,將其生成定時(shí)任務(wù),并進(jìn)行管理。

本質(zhì)還是管理的AbstractBaseCronTask子類在線程池中的具體對象,不同的地方是類級別定時(shí)任務(wù)是一個(gè)具體的任務(wù)類僅生成一個(gè)對象,class路徑即是唯一的標(biāo)識,而方法級別的定時(shí)任務(wù)均基于BaseMethodLevelTask生成無數(shù)個(gè)對象,具體標(biāo)識則是構(gòu)造函數(shù)傳入的Bean的反射對象和方法名。

對此部分感興趣的可以一起參與開發(fā),該項(xiàng)目地址:Gitee源碼,主要為其中task-component模塊。

3|0組件使用方法

根據(jù)Git地址,將源碼down下,編譯安裝到本地私倉中,以Maven的形式引入即可,該組件遵循Spring-starter規(guī)范,開箱即用。

<dependency>
            <groupId>com.gcc.container.components</groupId>
            <artifactId>task-component</artifactId>
            <version>1.0.0</version>
        </dependency>

3|1Yaml配置說明

給出一個(gè)yaml模板:

gcc-task:
  task-class-package : *
  data-file-path: /opt/myproject/task_info.json

對于task-component的配置只有兩個(gè),task-class-packagedata-file-path

屬性說明是否必須缺省值
task-class-package

指定定時(shí)任務(wù)存放的包路徑,不填寫或無此屬性則默認(rèn)全項(xiàng)目掃描,填寫后可有效減少初始化時(shí)間

*
data-file-path

定時(shí)任務(wù)管理的數(shù)據(jù)存放文件及其路徑,默認(rèn)不填寫則存放項(xiàng)目運(yùn)行目錄下,如自行擴(kuò)展實(shí)現(xiàn),則該配置自動失效

class:db/task_info.json

此處的兩個(gè)配置項(xiàng)都包含默認(rèn)值,所以不進(jìn)行yml的gcc-task仍舊可以使用該組件

3|2新建定時(shí)任務(wù)

對于該組件在進(jìn)行定時(shí)任務(wù)的創(chuàng)建時(shí),有兩種,分別是類級定時(shí)任務(wù)和方法級定時(shí)任務(wù),兩者的區(qū)別在于是以類為基本的單位還是以方法為一個(gè)定時(shí)任務(wù)的單位,對于運(yùn)行效果則并無區(qū)別,根據(jù)個(gè)人喜好,選擇使用哪一種即可

類級定時(shí)任務(wù)

新增一個(gè)定時(shí)任務(wù)邏輯,則需要實(shí)現(xiàn)基類AbstractBaseCronTask ,并加入注解 @ClassJob

ClassJob的參數(shù)如下

參數(shù)說明樣例
cron定時(shí)任務(wù)默認(rèn)的執(zhí)行周期,僅在首次初始化該任務(wù)使用(必填10 0/2 * * * ?
desc任務(wù)描述,非必填這是測試任務(wù)
bootup是否開機(jī)自啟動,缺省值為 falsefalse

cron 屬性僅在第一次新增該任務(wù)時(shí)提供一個(gè)默認(rèn)的執(zhí)行周期,必須填寫,后續(xù)任務(wù)加載后,定時(shí)任務(wù)相關(guān)數(shù)據(jù)會被存放在文件或數(shù)據(jù)庫中,此時(shí)則以文件或數(shù)據(jù)庫中該任務(wù)的cron為主,代碼中的注解則不會生效,如果想重置,則刪除已經(jīng)持久化的任務(wù)即可。

一個(gè)完整的Demo如下:

@TaskJob(cron = "10 0/2 * * * ?" ,desc = "這是一個(gè)測試任務(wù)",bootup = true)
public class TaskMysqlOne extends AbstractBaseCronTask {
    public TaskMysqlOne(TaskEntity taskEntity) {
        super(taskEntity);
    }
    @Override
    public void beforeJob() {
    }
    @Override
    public void startJob() {
    }
    @Override
    public void afterJob() {
    }
}

繼承AbstractBaseCronTask 必須要實(shí)現(xiàn)攜帶TaskEntity參數(shù)的構(gòu)造函數(shù)、beforeJob()、startJob() 、afterJob() 三個(gè)方法即可。原則上這三個(gè)方法是規(guī)范定時(shí)任務(wù)的執(zhí)行,實(shí)際使用,只需要把核心邏輯放在三個(gè)方法中任何一個(gè)即可。

因定時(shí)任務(wù)類是非SpringBean管理的類,所以在自定義的定時(shí)任務(wù)類內(nèi)無法使用任何Spring相關(guān)的注解(如@Autowired),但是卻可以通過自帶的getServer(Class<T> className)方法來獲取任何Spring上下文中的Bean

例如,你有一個(gè)UserService的接口及其Impl的實(shí)現(xiàn)類,想在定時(shí)任務(wù)類中使用該Bean,則可以:

@TaskJob(cron = "10 0/2 * * * ?" ,desc = "這是一個(gè)測試任務(wù)",bootup = true)
public class TaskMysqlOne extends AbstractBaseCronTask {
    public TaskMysqlOne(TaskEntity taskEntity) {
        super(taskEntity);
    }
    @Override
    public void beforeJob() {
    }
    @Override
    public void startJob() {
        List<String> names = getServer(UserService.class).searchAllUserName();
        //后續(xù)邏輯……
        //其他邏輯
    }
    @Override
    public void afterJob() {
    }
}

方法級定時(shí)任務(wù)

如果不想新建類,或者不想受限于AbstractBaseCronTask的束縛,則可以像xxl-job定義定時(shí)任務(wù)一樣,直接在某個(gè)方法上標(biāo)注@MethodJob注解即可。

@MethodJob的參數(shù)如下:

參數(shù)說明樣例
cron定時(shí)任務(wù)默認(rèn)的執(zhí)行周期,僅在首次初始化該任務(wù)使用(必填10 0/2 * * * ?
desc任務(wù)描述,非必填這是測試任務(wù)
bootup是否開機(jī)自啟動,缺省值為 falsefalse

通ClassJob一樣,cron 屬性僅在第一次新增該任務(wù)時(shí)提供一個(gè)默認(rèn)的執(zhí)行周期,必須填寫,后續(xù)任務(wù)加載后,定時(shí)任務(wù)相關(guān)數(shù)據(jù)會被存放在文件或數(shù)據(jù)庫中,此時(shí)則以文件或數(shù)據(jù)庫中該任務(wù)的cron為主,代碼中的注解則不會生效,如果想重置,則刪除已經(jīng)持久化的任務(wù)即可。

下面是一個(gè)例子:

//正常定義的Service接口
public interface AsyncTestService {
    void  taskJob();
}
//Service接口實(shí)現(xiàn)類
@Service
public class AsyncTestServiceImpl implements AsyncTestService {
    @MethodJob(cron = "11 0/1 * * * ?",desc = "這是個(gè)方法級任務(wù)")
    @Override
    public void taskJob() {
        log.info("方法級別任務(wù)查詢關(guān)鍵字為企業(yè)的數(shù)據(jù)");
        QueryWrapper<ArticleEntity> query = new QueryWrapper<>();
        query.like("art_name","企業(yè)");
        List<ArticleEntity> data = articleMapper.selectList(query);
        log.info("查出條數(shù)為{}",data.size());
    }
}

注:該注解僅支持SpringBoot中標(biāo)注為@Component、@Service@Repository的Bean

3|3動態(tài)調(diào)度任務(wù)接口說明

定時(shí)任務(wù)相關(guān)的管理操作均封裝在TaskScheduleManagerService接口中,接口內(nèi)容如下:

public interface TaskScheduleManagerService {
    /**
     * 查詢在用任務(wù)
     * @return
     */
    List<TaskVo> searchTask(SearchTaskDto dto);
    /**
     * 查詢?nèi)蝿?wù)詳情
     * @param taskId 任務(wù)id
     * @return TaskEntity
     */
    TaskVo searchTaskDetail(String taskId);
    /**
     * 運(yùn)行指定任務(wù)
     * @param taskId 任務(wù)id
     * @return TaskRunRetDto
     */
    TaskRunRetVo runTask(String taskId);
    /**
     * 關(guān)停任務(wù)
     * @param taskId 任務(wù)id
     * @return TaskRunRetDto
     */
    TaskRunRetVo shutdownTask(String taskId);
    /**
     * 開啟任務(wù)
     * @param taskId 任務(wù)id
     * @return TaskRunRetDto
     */
    TaskRunRetVo openTask(String taskId);
    /**
     * 更新任務(wù)信息
     * @param entity 實(shí)體
     * @return TaskRunRetDto
     */
    TaskRunRetVo updateTaskBusinessInfo(TaskEntity entity);
}

可直接在外部項(xiàng)目中注入使用即可:

@RestController
@RequestMapping("/myself/manage")
public class TaskSchedulingController {
    //引入依賴后可直接使用注入
    @Autowired
    private TaskScheduleManagerService taskScheduleManagerService;
    @GetMapping("/detail")
    @Operation(summary = "具體任務(wù)對象")
    public Response searchDetail(String taskId){
        return Response.success(taskScheduleManagerService.searchTaskDetail(taskId));
    }
    @GetMapping("/shutdown")
    @Operation(summary = "關(guān)閉指定任務(wù)")
    public Response shutdownTask(String taskId){
        return Response.success(taskScheduleManagerService.shutdownTask(taskId));
    }
    @GetMapping("/open")
    @Operation(summary = "開啟指定任務(wù)")
    public Response openTask(String taskId){
        return Response.success(taskScheduleManagerService.openTask(taskId));
    }
}

接口效果:

可使用該接口,進(jìn)行UI頁面開發(fā)。

3|4關(guān)于任務(wù)持久化的擴(kuò)展

在實(shí)現(xiàn)思路中提到過,task-component的執(zhí)行原理需要將注冊后的任務(wù)持久化,下次再啟動項(xiàng)目時(shí),則直接使用持久化的TaskEntity來加載定時(shí)任務(wù)。

考慮到定時(shí)任務(wù)的數(shù)量不大,且對于交互要求不高,另外考慮封裝成組件的獨(dú)立性普適性,不想額外引入數(shù)據(jù)庫依賴和ORM框架,所以組件默認(rèn)的是以JSON文件的形式進(jìn)行存儲,實(shí)際使用中,考慮到便利性,可以自行對持久化部分進(jìn)行擴(kuò)展。

所謂持久化,其實(shí)本制是持久化TaskEntity對象,TaskEntity對象如下:

@Data
public class TaskEntity implements Serializable {
    /**
    * 任務(wù)ID(唯一)
    */
    private String taskId;
    /**
    * 任務(wù)名稱
    */
    private String taskName;
    /**
    * 任務(wù)描述
    */
    private String taskDesc;
    /**
    * 遵循cron 表達(dá)式
    */
    private String taskCron;
    /**
     * 類路徑
     */
    private String taskClass;
     /**
     * 任務(wù)級別  CLASS_LEVEL 類級別,METHOD_LEVEL 方法級別
     */
    private TaskLevel taskLevel;
    /**
     * 任務(wù)注冊時(shí)間
     */
    private String taskCreateTime;
    /**
     * 是否啟用,1啟用,0不啟用
     */
    private Integer taskIsUse;
    /**
     * 是否系統(tǒng)啟動后立刻運(yùn)行 1是。0否
     */
    private Integer taskBootUp;
    /**
     * 上次運(yùn)行狀態(tài) 1:成功,0:失敗
     */
    private Integer taskLastRun;
    /**
     * 任務(wù)是否在內(nèi)存中 1:是,0:否
     */
    private Integer taskRamStatus;
     /**
     * 外部配置 (擴(kuò)展待使用字段)
     */
    private String taskOutConfig;
    /**
     * 加載配置
     */
    private String loadConfigure;
}

擴(kuò)展的主要操作為兩步:

  • 新建存放taskEntity的表
  • 實(shí)現(xiàn)TaskRepository接口 

首先新建數(shù)據(jù)庫表,這里以Mysql為例給出建表語句:

DROP TABLE IF EXISTS `tb_task_info`;
CREATE TABLE `tb_task_info` (
  `task_id` varchar(100) NOT NULL PRIMARY KEY ,
  `task_name` varchar(255) DEFAULT NULL,
  `task_desc` text,
  `task_cron` varchar(20) DEFAULT NULL,
  `task_class` varchar(100) DEFAULT NULL COMMENT '定時(shí)任務(wù)類路徑',
  `task_level` varchar(50) DEFAULT NULL COMMENT '任務(wù)級別:類級別(CLASS_LEVEL)、方法級別(METHOD_LEVEL)',
  `task_is_use` tinyint DEFAULT NULL COMMENT '是否啟用該任務(wù),1:啟用,0禁用',
  `task_boot_up` tinyint DEFAULT NULL COMMENT '是否為開機(jī)即運(yùn)行,1:初始化即運(yùn)行,0,初始化不運(yùn)行',
  `task_out_config` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci COMMENT '定時(shí)任務(wù)額外配置項(xiàng),采用json結(jié)構(gòu)存放',
  `task_create_time` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '定時(shí)任務(wù)追加時(shí)間',
  `task_last_run` tinyint DEFAULT NULL COMMENT '任務(wù)上次執(zhí)行狀態(tài);1正常,0執(zhí)行失敗,null未知',
  `task_ram_status` tinyint DEFAULT NULL COMMENT '任務(wù)當(dāng)前狀態(tài);1內(nèi)存運(yùn)行中,0內(nèi)存移除',
  `loadConfigure` text  COMMENT '加載相關(guān)配置',  
PRIMARY KEY (`task_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC;

實(shí)現(xiàn)TaskEntityRepository 接口,接口內(nèi)容為:

public interface TaskEntityRepository {
    /**
     * 新增數(shù)據(jù)
     * @param entity
     * @return int
     */
    int save(TaskEntity entity);
    /**
     * 刪除任務(wù),根據(jù)TaskId
     * @param id id
     * @return int
     */
    int removeByTaskId(String id);
     /**
     * 更新任務(wù)(除taskId外,所有字段必須更新)
     * @param entity 實(shí)體
     * @return int
     */
    int update(TaskEntity entity);
    /**
     * 查詢?nèi)咳蝿?wù)
     * @return List<TaskEntity>
     */
    List<TaskEntity> queryAllTask();
}

只需要新建類,然后實(shí)現(xiàn)該接口即可,如下是基于Mybatis-Plus進(jìn)行的實(shí)現(xiàn)樣例:

@Mapper
public interface TaskDataMapper extends BaseMapper<TaskEntity> {
}
@Repository
//此處一定要用@Primary注解進(jìn)行固定
@Primary
public class TaskEntityReponsitoryImpl implements TaskEntityRepository {
    @Autowired
    private TaskDataMapper taskDataMapper;
    @Override
    public int save(TaskEntity entity) {
        entity.setTaskCreateTime(DateUtil.now());
        return taskDataMapper.insert(entity);
    }
    @Override
    public int removeByTaskId(String id) {
        QueryWrapper<TaskEntity> query = new QueryWrapper<>();
        query.eq("task_id",id);
        return taskDataMapper.delete(query);
    }
    @Override
    public int update(TaskEntity entity) {
        UpdateWrapper<TaskEntity> update = new UpdateWrapper<>();
        update.eq("task_id",entity.getTaskId());
        return taskDataMapper.update(entity,update);
    }
    @Override
    public List<TaskEntity> queryAllTask() {
        return taskDataMapper.selectList(new QueryWrapper<>());
    }
}

至此,項(xiàng)目中則可以以數(shù)據(jù)庫表的形式來管理定時(shí)任務(wù):

任務(wù)運(yùn)行日志:

[main] com.web.test.Application                 : Started Application in 3.567 seconds (JVM running for 4.561)
[main] .g.c.c.t.c.InitTaskSchedulingApplication : 【定時(shí)任務(wù)初始化】 容器初始化
[main] o.s.s.c.ThreadPoolTaskScheduler          : Initializing ExecutorService
[main] .g.c.c.t.c.InitTaskSchedulingApplication : 【定時(shí)任務(wù)初始化】定時(shí)任務(wù)初始化任務(wù)開始
[main] c.g.c.c.task.compont.TaskScheduleImpl    : 【定時(shí)任務(wù)初始化】裝填任務(wù):TaskTwoPerson [ 任務(wù)執(zhí)行周期:15 0/2 * * * ? ] [ bootup:0]
[main] c.g.c.c.task.compont.TaskScheduleImpl    : 【定時(shí)任務(wù)初始化】裝填任務(wù):TaskMysqlOne [ 任務(wù)執(zhí)行周期:10 0/2 * * * ? ] [ bootup:1]
[main] c.g.c.c.task.compont.TaskScheduleImpl    : 【定時(shí)任務(wù)初始化】裝填任務(wù):taskJob [ 任務(wù)執(zhí)行周期:11 0/1 * * * ? ] [ bootup:0]
[main] .g.c.c.t.c.InitTaskSchedulingApplication : 【定時(shí)任務(wù)初始化】定時(shí)任務(wù)初始化任務(wù)完成
[main] c.g.c.c.task.service.AfterAppStarted     : 【定時(shí)任務(wù)自運(yùn)行】運(yùn)行開機(jī)自啟動任務(wù)
[main] TaskMysqlOne                             : ---------------------任務(wù) TaskMysqlOne 開始執(zhí)行-----------------------
[main] TaskMysqlOne                             : 任務(wù)描述:這是一個(gè)測試任務(wù)
[main] TaskMysqlOne                             : 我是張三
[main] TaskMysqlOne                             : 任務(wù)耗時(shí):約 0.0 s
[main] TaskMysqlOne                             : ---------------------任務(wù) TaskMysqlOne 結(jié)束執(zhí)行-----------------------
[task-thread-1] taskJob                                  : ---------------------任務(wù) taskJob 開始執(zhí)行-----------------------
[task-thread-1] taskJob                                  : 任務(wù)描述:這是個(gè)方法級任務(wù)
[task-thread-1] c.w.t.service.impl.AsyncTestServiceImpl  : 方法級別任務(wù)查詢關(guān)鍵字為企業(yè)的數(shù)據(jù)
[task-thread-1] c.w.t.service.impl.AsyncTestServiceImpl  : 查出條數(shù)為1
[task-thread-1] taskJob                                  : 任務(wù)耗時(shí):約 8.45 s
[task-thread-1] taskJob                                  : ---------------------任務(wù) taskJob 結(jié)束執(zhí)行-------------------

到此這篇關(guān)于SpringBoot實(shí)現(xiàn)輕量級動態(tài)定時(shí)任務(wù)管控及組件化的文章就介紹到這了,更多相關(guān)SpringBoot定時(shí)任務(wù)管控內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot整合JWT實(shí)現(xiàn)登錄認(rèn)證與接口授權(quán)的全流程

    SpringBoot整合JWT實(shí)現(xiàn)登錄認(rèn)證與接口授權(quán)的全流程

    JWT作為一種輕量級的身份認(rèn)證與授權(quán)方案,憑借其無狀態(tài)、可跨域、易于擴(kuò)展的特性,成為?Spring?Boot?項(xiàng)目中實(shí)現(xiàn)認(rèn)證授權(quán)的主流選擇,本文將從環(huán)境搭建、核心實(shí)現(xiàn)到進(jìn)階優(yōu)化,完整講解?Spring?Boot?整合?JWT?實(shí)現(xiàn)登錄認(rèn)證與接口授權(quán)的全流程,需要的朋友可以參考下
    2025-12-12
  • 使用Aop的方式實(shí)現(xiàn)自動日志記錄的方式詳細(xì)介紹

    使用Aop的方式實(shí)現(xiàn)自動日志記錄的方式詳細(xì)介紹

    這篇文章主要介紹了使用Aop的方式實(shí)現(xiàn)自動日志記錄,通過監(jiān)聽器去監(jiān)聽,當(dāng)訪問到具體的類方法,通過aop切面去獲取訪問的方法,然后將日志記錄下來,就這種方式給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • Java實(shí)現(xiàn)自定義LinkedList類的示例代碼

    Java實(shí)現(xiàn)自定義LinkedList類的示例代碼

    LinkedList類跟ArrayList類不同,它通過指針以及結(jié)點(diǎn)的操作對鏈表進(jìn)行增刪改查。本文就來和大家分享下Java如何為實(shí)現(xiàn)自定義LinkedList類,需要的可以參考一下
    2022-08-08
  • Java連接MYSQL數(shù)據(jù)庫的實(shí)現(xiàn)步驟

    Java連接MYSQL數(shù)據(jù)庫的實(shí)現(xiàn)步驟

    以下的文章主要描述的是java連接MYSQL數(shù)據(jù)庫的正確操作步驟,在此篇文章里我們主要是以實(shí)例列舉的方式來引出其具體介紹
    2013-06-06
  • 解決Spring?Boot應(yīng)用打包后文件訪問問題

    解決Spring?Boot應(yīng)用打包后文件訪問問題

    在Spring Boot項(xiàng)目的開發(fā)過程中,一個(gè)常見的挑戰(zhàn)是如何有效地訪問和操作資源文件,本文就來介紹一下解決Spring?Boot應(yīng)用打包后文件訪問問題,感興趣的可以了解一下
    2024-01-01
  • springsecurity6配置自定義路徑身份認(rèn)證的實(shí)現(xiàn)

    springsecurity6配置自定義路徑身份認(rèn)證的實(shí)現(xiàn)

    本文主要介紹了springsecurity6配置自定義路徑身份認(rèn)證的實(shí)現(xiàn),通過使用自定義的AuthorizationManager和MyService,可以實(shí)現(xiàn)更靈活的訪問控制,感興趣的可以了解一下
    2025-03-03
  • springBoot整合rabbitMQ的方法詳解

    springBoot整合rabbitMQ的方法詳解

    這篇文章主要介紹了springBoot整合rabbitMQ的方法詳解,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • mybatis如何獲取剛剛新插入數(shù)據(jù)的主鍵值id

    mybatis如何獲取剛剛新插入數(shù)據(jù)的主鍵值id

    這篇文章主要介紹了mybatis如何獲取剛剛新插入數(shù)據(jù)的主鍵值id問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • JAVA驗(yàn)證碼工具實(shí)例代碼

    JAVA驗(yàn)證碼工具實(shí)例代碼

    這篇文章主要介紹了JAVA驗(yàn)證碼工具實(shí)例代碼,需要的朋友可以參考下
    2018-03-03
  • JetBrains的IDEA編輯器自動配置的JDK版本下載目錄過程

    JetBrains的IDEA編輯器自動配置的JDK版本下載目錄過程

    文章說明Java安裝路徑為~/Library/Java/JavaVirtualMachines/ms-17.0.16,并分享配置經(jīng)驗(yàn),建議用戶根據(jù)實(shí)際需求調(diào)整環(huán)境變量,以確保Java版本正確運(yùn)行
    2025-08-08

最新評論

翁牛特旗| 建德市| 五台县| 芒康县| 和平县| 阜城县| 陈巴尔虎旗| 临江市| 榕江县| 霍山县| 常德市| 徐闻县| 天峨县| 青神县| 陆河县| 福州市| 天柱县| 常宁市| 綦江县| 凯里市| 巴楚县| 都安| 柳江县| 昭平县| 古田县| 无锡市| 集贤县| 宾川县| 晋宁县| 湘乡市| 新巴尔虎右旗| 襄垣县| 河东区| 宣汉县| 肇州县| 张家界市| 盐津县| 张北县| 龙南县| 天镇县| 京山县|