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

Spring Task定時任務開發(fā)實戰(zhàn)教程

 更新時間:2026年03月07日 11:08:55   作者:加洛斯  
文章介紹了SpringTask,這是Spring框架提供的用于實現定時任務的模塊,它基于注解和配置方式,簡化了任務調度的實現,本文結合實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧

大家好,我是加洛斯。作為一名程序員??‍??,我深深信奉費曼學習法——教,是最好的學 ??。這里是我的知識筆記與分享,旨在把復雜的東西講明白。如果發(fā)現有誤??,萬分歡迎你幫我指出來!廢話不多說,正文開始 ??

一、基礎知識

Spring TaskSpring 框架提供的任務調度模塊,用于實現定時任務功能。它是 Spring3.0 后引入的,基于注解和配置的方式,簡化了任務調度的實現。

  • 輕量級:無需引入額外的調度框架(如 Quartz)
  • 注解驅動:通過 @Scheduled 注解即可定義定時任務
  • 集成簡單:與 Spring 框架無縫集成
  • 支持 Cron 表達式:提供靈活的定時規(guī)則定義

Spring Task的依賴是org.springframework.boot,這個在我們創(chuàng)建項目的時候就存在的,一般情況下來講我們不需要額外引入,但是以防萬一我們還是在pom文件中查找一下是否存在。

<!-- Spring Boot 項目依賴 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

啟用定時任務:想要開啟定時任務我們需要在main方法中添加注解@EnableScheduling。

@SpringBootApplication
@EnableScheduling  // 開啟定時任務支持
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

我們來簡單的舉個小例子來講述一下,看這個例子當中我們是不是有很多注解不明白?我們來詳細的講一下。

@Component
public class TaskTest {
    // 固定頻率執(zhí)行,每5秒執(zhí)行一次
    @Scheduled(fixedRate = 5000)
    public void executeFixedRate() {
        System.out.println("固定頻率任務執(zhí)行: " + new Date());
    }
    // 固定延遲執(zhí)行,上次執(zhí)行完成后延遲3秒執(zhí)行
    @Scheduled(fixedDelay = 3000)
    public void executeFixedDelay() {
        System.out.println("固定延遲任務執(zhí)行: " + new Date());
        try {
            Thread.sleep(1000); // 模擬任務執(zhí)行時間
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    // 初始延遲2秒后開始執(zhí)行,然后每10秒執(zhí)行一次
    @Scheduled(initialDelay = 2000, fixedRate = 10000)
    public void executeWithInitialDelay() {
        System.out.println("帶初始延遲的任務執(zhí)行: " + new Date());
    }
}

二、@Scheduled注解參數詳解

@ScheduledSpring Framework 3.0 引入的注解,用于聲明一個方法是定時任務方法。這是 Spring Task 調度的核心注解。

//基本使用
@Component
public class MyScheduledTasks {
    @Scheduled(fixedRate = 5000)
    public void myTask() {
        // 任務邏輯
    }
}

2.1 fixedRate(固定頻率執(zhí)行)

作用:以固定頻率執(zhí)行任務,不管上一次任務是否完成。

  1. 固定速率:無論上次任務是否完成,到時間就會啟動新執(zhí)行
  2. 相對開始時間:從上次開始執(zhí)行的時間點計算下一次執(zhí)行,上一次任務開始執(zhí)行后,間隔指定時間就會觸發(fā)下一次執(zhí)行
  3. 獨立線程:默認使用單線程,可能發(fā)生任務重疊

@Scheduled(fixedRate = ) 后面可以接受多種類型的值,最常見的是long類型的毫秒值與TimeUnit時間單位(Spring 5.3+)

@Component
@Slf4j
public class FixedRateExample {
    private AtomicInteger counter = new AtomicInteger(0);
    /**
     * 每1秒執(zhí)行一次
     */
    @Scheduled(fixedRate = 1000)
    public void fixedRateTask() {
        int count = counter.incrementAndGet();
        log.info("fixedRate 任務開始執(zhí)行,第{}次", count);
        try {
            // 模擬任務執(zhí)行時間
            Thread.sleep(5000); // 任務執(zhí)行需要5秒
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        log.info("fixedRate 任務結束執(zhí)行,第{}次", count);
    }
}

觀察上述代碼,我們可以看到,這段代碼并沒有并發(fā)執(zhí)行 這是為什么呢?

這是因為 Spring 默認使用單線程的線程池執(zhí)行定時任務。

  1. @Scheduled 默認行為
    • Spring 的 @Scheduled 默認使用 ThreadPoolTaskScheduler,默認配置下只有一個線程
    • 默認線程池名稱是 scheduling-1(從日志中可以看到)
  2. fixedRate 的原理
    • fixedRate = 1000 意味著 每隔1秒應該開始一次新的執(zhí)行
    • 但是如果前一個任務還在執(zhí)行,且沒有可用線程,新任務會在隊列中等待
    • 在日志中,任務都是串行執(zhí)行的,因為只有一個線程

如果你確定這段代碼可以并且需要并發(fā)執(zhí)行,那么有多種方案可以解決當前的問題。我們最推薦的就是使用異步注解。

@Component
@Slf4j
@EnableAsync  // 啟用異步支持
public class TaskTest {
    private AtomicInteger counter = new AtomicInteger(0);
    /**
     * 每1秒執(zhí)行一次
     */
    @Async  // 添加異步注解
    @Scheduled(fixedRate = 1000)
    public void fixedRateTask() {
        int count = counter.incrementAndGet();
        log.info("fixedRate 任務開始執(zhí)行,第{}次", count);
        try {
            // 模擬任務執(zhí)行時間
            Thread.sleep(5000); // 任務執(zhí)行需要5秒
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        log.info("fixedRate 任務結束執(zhí)行,第{}次", count);
    }
}

可以看到啟動異步注解后,我們的定時任務并發(fā)執(zhí)行了。但是有一個問題,@Async 注解本身不會固定開啟幾個線程,它的行為取決于你如何配置線程池。在這種情況下在這種情況下:

  • Spring 會使用 SimpleAsyncTaskExecutor
  • 每個異步任務都會創(chuàng)建一個新線程(無限制)
  • 線程不會重用(執(zhí)行完就銷毀)
  • 這可能會導致創(chuàng)建大量線程,有內存泄露風險

所以我們需要配置線程池控制線程數量

spring:
  task:
    execution:
      pool:
        core-size: 3      # 核心線程數
        max-size: 5      # 最大線程數
        keep-alive: 60s   # 空閑線程存活時間
      thread-name-prefix: async-

以防有人不知道多線程策略,這里簡單講一下

任務提交順序:

  1. 先使用核心線程(corePoolSize)
  2. 核心線程滿了 → 放入隊列(queueCapacity)
  3. 隊列滿了 → 創(chuàng)建新線程直到最大線程數(maxPoolSize)
  4. 都滿了 → 執(zhí)行拒絕策略

示例配置(core=5, max=10, queue=25):

  • 同時處理5個任務 → 5個核心線程
  • 又來第6-30個任務 → 放入隊列(25個)
  • 又來第31-40個任務 → 創(chuàng)建新線程(總共10個線程)
  • 再來任務 → 執(zhí)行拒絕策略

這樣看我們最多只啟用了三個線程,線程過少可能也會導致線程阻塞,所以我們需要根據實際情況進行修改。

2.2 fixedDelay(固定延遲執(zhí)行)

作用:上一次任務執(zhí)行完成后,延遲指定時間再執(zhí)行下一次。

  • 保證任務串行執(zhí)行
  • 不會出現并發(fā)執(zhí)行的情況
@Component
@Slf4j
public class FixedDelayExample {
    private AtomicInteger counter = new AtomicInteger(0);
    /**
     * 上次任務執(zhí)行完成后,延遲3秒再執(zhí)行
     */
    @Scheduled(fixedDelay = 3000)
    public void fixedDelayTask() {
        int count = counter.incrementAndGet();
        log.info("fixedDelay 任務開始執(zhí)行,第{}次", count);
        try {
            // 模擬任務執(zhí)行時間
            Thread.sleep(5000); // 任務執(zhí)行需要5秒
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        log.info("fixedDelay 任務結束執(zhí)行,第{}次", count);
    }
}

2.3 initialDelay(初始延遲)

作用:應用啟動后,延遲指定時間再開始執(zhí)行第一次任務。

  • 通常與 fixedRate 或 fixedDelay 配合使用
  • 避免應用啟動時立即執(zhí)行所有任務
@Component
@Slf4j
@EnableAsync  // 啟用異步支持
public class TaskTest {
    private AtomicInteger counter = new AtomicInteger(0);
    /**
     * 應用啟動30秒后開始執(zhí)行,之后每10秒執(zhí)行一次
     */
    @Scheduled(initialDelay = 30000, fixedRate = 10000)
    public void taskWithInitialDelay() {
        log.info("帶初始延遲的任務執(zhí)行,當前時間: {}",
                LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME));
    }
}

2.4 Cron 表達式

Cron 表達式是一個字符串,由 6 或 7 個字段組成,用于定義定時任務的執(zhí)行時間。

注意:Spring中的Cron表達式與標準Unix Cron的主要區(qū)別:

  • 秒字段:Spring支持秒級精度(第一位),標準Cron沒有
  • 星期幾:Spring中1-7表示周一到周日(或MON-SUN),0和7表示周日
// 每分鐘的第30秒執(zhí)行
@Scheduled(cron = "30 * * * * *")
public void everyMinuteAt30() {
    log.info("每分鐘的第30秒執(zhí)行");
}

我們可以看到cron后面接了一堆***,這又是什么意思呢?我們看下面的圖

特殊字符說明

字符含義示例說明
*任意值* * * * * *每秒執(zhí)行
?不指定值0 0 12 * * ?僅用于日和星期字段
-范圍0 0 10-12 * * *10點、11點、12點
,多個值0 0 10,14,16 * * *10點、14點、16點
/步長0 0/5 * * * *每5分鐘
L最后0 0 0 L * ?每月最后一天
W工作日0 0 0 15W * ?最近的工作日
#第幾個星期幾0 0 0 ? * 2#3每月第3個周一
  • 不指定值:這對應表達式中的  ?  問號。在 Cron 中,? 用于  “不關心”或“無特定值”  的字段。它只能用在你不想指定具體值的字段上。
  • 僅用于日和星期字段:這是一個非常重要的規(guī)則說明。它告訴你 ? 這個符號只能出現在“日期(日)”字段和“星期幾”字段中。

為什么有這個規(guī)則?

因為在 Cron 表達式的邏輯中, “日期(日)”和“星期幾”本質上表達的是同一種概念(一個月的哪一天) 。如果你同時指定了“每月15號”和“每個星期二”,調度器就會困惑:你到底是想在“每月15號”運行,還是“每個星期二”運行,還是“既是15號又是星期二”才運行?

為了消除這種歧義,Quartz 規(guī)定:

  1. 在星期字段使用 * 實際上是允許的,它被視為“不指定具體星期幾”

  2. 真正的限制是:不能同時指定具體的日和具體的星期

    • 錯誤:* * * 15 * MON (指定了15號和周一)
    • 正確:* * * 15 * ? 或 * * * ? * MON
    • 可以* * * * * * (日和星期都是 *,這是允許的)

這些個表達式認識就好,只要不是關小黑屋那種的開發(fā)就沒必須死磕,現在ai這么發(fā)達,直接把你想要的發(fā)給ai生成或者解析就行。

來看一堆例子

@Component
@Slf4j
public class CronExample {
    /**
     * 基本Cron表達式示例
     */
    // 每5秒執(zhí)行一次
    @Scheduled(cron = "*/5 * * * * *")
    public void everyFiveSeconds() {
        log.info("每5秒執(zhí)行一次");
    }
    // 每分鐘的第30秒執(zhí)行
    @Scheduled(cron = "30 * * * * *")
    public void everyMinuteAt30() {
        log.info("每分鐘的第30秒執(zhí)行");
    }
    // 每小時的第15分鐘執(zhí)行
    @Scheduled(cron = "0 15 * * * *")
    public void everyHourAt15() {
        log.info("每小時的第15分鐘執(zhí)行");
    }
    // 每天10:30執(zhí)行
    @Scheduled(cron = "0 30 10 * * *")
    public void dailyAt10_30() {
        log.info("每天10:30執(zhí)行");
    }
    /**
     * 復雜的Cron表達式示例
     */
    // 工作日的9點到17點,每半小時執(zhí)行
    @Scheduled(cron = "0 */30 9-17 * * MON-FRI")
    public void workHoursTask() {
        log.info("工作時間任務執(zhí)行");
    }
    // 每月1號凌晨2點執(zhí)行
    @Scheduled(cron = "0 0 2 1 * ?")
    public void monthlyTask() {
        log.info("每月任務執(zhí)行");
    }
    // 每個季度的第一天凌晨3點執(zhí)行
    @Scheduled(cron = "0 0 3 1 1,4,7,10 ?")
    public void quarterlyTask() {
        log.info("季度任務執(zhí)行");
    }
    /**
     * 特殊字符用法
     */
    // 'L' 表示最后一天
    @Scheduled(cron = "0 0 23 L * ?")
    public void lastDayOfMonth() {
        log.info("每月最后一天23:00執(zhí)行");
    }
    // 'W' 表示最近的工作日
    @Scheduled(cron = "0 0 12 15W * ?")
    public void nearestWeekday() {
        log.info("每月15號最近的工作日12:00執(zhí)行");
    }
    // '#' 表示第幾個星期幾
    @Scheduled(cron = "0 0 10 ? * 2#2")  // 每月第二個星期一10:00
    public void secondMondayOfMonth() {
        log.info("每月第二個星期一執(zhí)行");
    }
    /**
     * 從配置文件讀取Cron表達式
     */
    @Scheduled(cron = "${task.cron.expression:0 0/30 * * * *}")
    public void configurableCronTask() {
        log.info("可配置的Cron任務執(zhí)行");
    }
    /**
     * 使用Zone指定時區(qū)
     */
    @Scheduled(cron = "0 0 9 * * *", zone = "Asia/Shanghai")
    public void timezoneSpecificTask() {
        log.info("上海時區(qū)每天9:00執(zhí)行");
    }
    /**
     * 動態(tài)Cron表達式(使用SpEL)
     */
    @Scheduled(cron = "#{@cronExpressionProvider.getCron()}")
    public void dynamicCronTask() {
        log.info("動態(tài)Cron表達式任務執(zhí)行");
    }
}

三、參數組合使用

3.1 參數優(yōu)先級說明

  • cron 參數優(yōu)先級最高,如果設置了 cron,其他時間參數會被忽略
  • fixedRate 和 fixedDelay 不能同時使用
  • initialDelay 只能與 fixedRate 或 fixedDelay 一起使用
@Component
@Slf4j
public class ParameterCombinationExample {
    /**
     * 正確的組合:initialDelay + fixedRate
     */
    @Scheduled(initialDelay = 10000, fixedRate = 5000)
    public void validCombination1() {
        log.info("initialDelay + fixedRate 組合任務");
    }
    /**
     * 正確的組合:initialDelay + fixedDelay
     */
    @Scheduled(initialDelay = 5000, fixedDelay = 3000)
    public void validCombination2() {
        log.info("initialDelay + fixedDelay 組合任務");
    }
    /**
     * 錯誤的組合:fixedRate + fixedDelay (編譯不會報錯,但運行時只會生效一個)
     */
    @Scheduled(fixedRate = 5000, fixedDelay = 3000)
    public void invalidCombination() {
        log.warn("fixedRate 和 fixedDelay 同時設置,這是不推薦的!");
        // 實際上只會按照 fixedDelay 執(zhí)行
    }
    /**
     * Cron表達式與其他參數組合(cron優(yōu)先級高,其他參數會被忽略)
     */
    @Scheduled(cron = "0 */5 * * * *", fixedRate = 10000)
    public void cronWithOtherParams() {
        log.info("設置了cron和fixedRate,只會按照cron執(zhí)行");
        // fixedRate 參數會被忽略
    }
}

四、動態(tài)配置參數

4.1 使用配置文件

# application.yml
scheduled:
  tasks:
    data-sync:
      enabled: true
      cron: "0 */30 * * * *"
      initial-delay: 10000
    report-generation:
      enabled: false
      cron: "0 0 2 * * *"
    cache-refresh:
      fixed-rate: 300000  # 5分鐘
@Component
@Slf4j
@ConditionalOnProperty(name = "scheduled.tasks.data-sync.enabled", havingValue = "true")
public class ConfigurableScheduledTask {
    /**
     * 從YAML配置文件讀取所有參數
     */
    @Scheduled(
        cron = "${scheduled.tasks.data-sync.cron}",
        initialDelayString = "${scheduled.tasks.data-sync.initial-delay:0}"
    )
    public void dataSyncTask() {
        log.info("數據同步任務執(zhí)行");
    }
    /**
     * 使用默認值的配置
     */
    @Scheduled(fixedRateString = "${scheduled.tasks.cache-refresh.fixed-rate:600000}")
    public void cacheRefreshTask() {
        log.info("緩存刷新任務執(zhí)行");
    }
}

4.2 使用SpEL表達式

@Component
@Slf4j
public class SpELExample {
    private final Environment environment;
    public SpELExample(Environment environment) {
        this.environment = environment;
    }
    /**
     * 使用SpEL讀取環(huán)境變量
     */
    @Scheduled(fixedRateString = "#{${task.interval.base} * ${task.interval.multiplier:1}}")
    public void spelCalculationTask() {
        log.info("SpEL計算間隔的任務執(zhí)行");
    }
    /**
     * 根據條件動態(tài)設置間隔
     */
    @Scheduled(fixedDelayString = "#{environment.getProperty('task.mode') == 'fast' ? 1000 : 5000}")
    public void conditionalIntervalTask() {
        log.info("條件間隔任務執(zhí)行");
    }
    /**
     * 調用Bean方法獲取配置
     */
    @Scheduled(cron = "#{@scheduleConfig.getDataExportCron()}")
    public void dataExportTask() {
        log.info("數據導出任務執(zhí)行");
    }
    /**
     * 復雜的SpEL表達式
     */
    @Scheduled(
        initialDelayString = "#{T(java.lang.Math).random() * 10000}",
        fixedRateString = "#{5000 + T(java.lang.Math).random() * 5000}"
    )
    public void randomIntervalTask() {
        log.info("隨機間隔任務執(zhí)行");
    }
}
@Component
class ScheduleConfig {
    @Value("${app.environment}")
    private String environment;
    public String getDataExportCron() {
        if ("prod".equals(environment)) {
            return "0 0 2 * * *";  // 生產環(huán)境:每天凌晨2點
        } else {
            return "0 */30 * * * *";  // 測試環(huán)境:每30分鐘
        }
    }
}

五、其他知識與注意事項

5.1 多個@Scheduled注解

Spring 4.0 開始支持同一個方法上使用多個 @Scheduled 注解:

@Component
@Slf4j
public class MultipleSchedulesExample {
    /**
     * 同一個方法多個調度規(guī)則
     * 方法會在多個時間點被調用
     */
    @Scheduled(cron = "0 0 9 * * *")   // 每天9點
    @Scheduled(cron = "0 0 18 * * *")  // 每天18點
    @Scheduled(cron = "0 0/30 9-18 * * MON-FRI")  // 工作日每30分鐘
    public void multiScheduledTask() {
        log.info("多調度任務執(zhí)行,當前時間: {}", LocalDateTime.now());
    }
    /**
     * 使用 @Schedules 注解(與上面等價)
     */
    @Schedules({
        @Scheduled(fixedRate = 5000),
        @Scheduled(fixedDelay = 10000),
        @Scheduled(cron = "0 0 12 * * *")
    })
    public void usingSchedulesAnnotation() {
        log.info("使用 @Schedules 注解的任務");
    }
}

5.2 與 @Transactional 結合

事務注解要放在 @Scheduled 下面

@Component
@Slf4j
public class TransactionalScheduledTask {
    @Autowired
    private UserRepository userRepository;
    /**
     * 帶事務的定時任務
     * 注意:事務注解要放在 @Scheduled 下面
     */
    @Scheduled(cron = "0 0 4 * * *")  // 每天凌晨4點
    @Transactional
    public void cleanupInactiveUsers() {
        log.info("開始清理非活躍用戶");
        try {
            // 刪除30天未登錄的用戶
            LocalDate cutoffDate = LocalDate.now().minusDays(30);
            int deletedCount = userRepository.deleteInactiveUsers(cutoffDate);
            log.info("清理完成,刪除 {} 個非活躍用戶", deletedCount);
        } catch (Exception e) {
            log.error("清理非活躍用戶失敗", e);
            // 事務會自動回滾
            throw e;
        }
    }
    /**
     * 使用 REQUIRES_NEW 事務傳播級別
     * 每次執(zhí)行都是獨立的事務
     */
    @Scheduled(fixedRate = 60000)  // 每分鐘
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateStatistics() {
        // 更新統(tǒng)計信息,即使失敗也不影響其他事務
        log.info("更新統(tǒng)計信息");
    }
}

5.3 常見陷阱

@Component
@Slf4j
public class CommonPitfalls {
    /**
     * 陷阱1:長時間運行的任務阻塞其他任務
     * 解決方案:使用異步執(zhí)行或調整線程池
     */
    @Scheduled(fixedRate = 1000)
    public void longRunningTask() {
        try {
            Thread.sleep(5000);  // 任務執(zhí)行5秒
            log.info("長時間任務完成");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    /**
     * 陷阱2:任務拋出異常導致后續(xù)任務不再執(zhí)行
     * 解決方案:捕獲異常并處理
     */
    @Scheduled(fixedDelay = 2000)
    public void exceptionProneTask() {
        try {
            // 可能拋出異常的代碼
            if (Math.random() > 0.8) {
                throw new RuntimeException("隨機異常");
            }
            log.info("任務正常執(zhí)行");
        } catch (Exception e) {
            log.error("任務執(zhí)行異常,但已處理", e);
            // 可以選擇重試、記錄日志、發(fā)送告警等
        }
    }
    /**
     * 陷阱3:不正確的Cron表達式
     */
    @Scheduled(cron = "0 0 * * * *")  // 正確:每小時執(zhí)行
    public void correctCron() {
        log.info("正確的Cron任務");
    }
    // @Scheduled(cron = "0 0 * * *")  // 錯誤:缺少秒字段
    // public void incorrectCron() {
    //     log.info("這個不會執(zhí)行");
    // }
    /**
     * 陷阱4:Bean未實例化就嘗試調度
     * 確保@Component或@Service注解被掃描到
     */
    /**
     * 陷阱5:忘記啟用調度
     * 必須在配置類上添加 @EnableScheduling
     */
}

到此這篇關于Spring Task定時任務開發(fā)實戰(zhàn)教程的文章就介紹到這了,更多相關Spring Task定時任務內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java 壓縮包解壓實現代碼

    Java 壓縮包解壓實現代碼

    Java標準庫(Java SE)提供了對ZIP格式的原生支持,通過java.util.zip包中的類來實現壓縮和解壓功能,本文將重點介紹如何使用Java來解壓ZIP或RAR壓縮包,感興趣的朋友一起看看吧
    2025-05-05
  • Java傳值調用和傳引用調用方式(參數引用為null問題)

    Java傳值調用和傳引用調用方式(參數引用為null問題)

    這篇文章主要介紹了Java傳值調用和傳引用調用方式(參數引用為null問題),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Spring Boot中日志管理與異常處理實踐指南

    Spring Boot中日志管理與異常處理實踐指南

    本文系統(tǒng)化講解SpringBoot日志管理與異常處理,涵蓋Logback配置、分層異常處理、上下文記錄及ELK集成,強調日志分級、自定義異常設計,增強應用穩(wěn)定性與可維護性,感興趣的朋友跟隨小編一起看看吧
    2025-06-06
  • SpringBoot解決跨域的5種方式小結

    SpringBoot解決跨域的5種方式小結

    在項目開發(fā)中,時常會遇到跨域問題,本文主要介紹了五種解決跨域的方法,使用最多的是第三種,需要的朋友們下面隨著小編來一起學習學習吧
    2021-06-06
  • Django rest framework使用類視圖實現首頁API

    Django rest framework使用類視圖實現首頁API

    這篇文章主要介紹了Django rest framework使用類視圖實現首頁API,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • Java實現游戲飛機大戰(zhàn)-III的示例代碼

    Java實現游戲飛機大戰(zhàn)-III的示例代碼

    這篇文章主要為大家介紹了如何利用Java實現經典的游戲之飛機大戰(zhàn),文中采用了swing技術進行了界面化處理,感興趣的小伙伴可以動手試一試
    2022-02-02
  • Java 面向對象的特征解析與應用

    Java 面向對象的特征解析與應用

    Java 是面向對象的編程語言,對象就是面向對象程序設計的核心。所謂對象就是真實世界中的實體,對象與實體是一一對應的,也就是說現實世界中每一個實體都是一個對象,它是一種具體的概念
    2021-11-11
  • Java 實現簡單靜態(tài)資源Web服務器的示例

    Java 實現簡單靜態(tài)資源Web服務器的示例

    這篇文章主要介紹了Java 實現簡單靜態(tài)資源Web服務器的示例,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-11-11
  • JSP安全開發(fā)之XSS漏洞詳解

    JSP安全開發(fā)之XSS漏洞詳解

    XSS又叫CSS (Cross Site Script) ,跨站腳本攻擊。它指的是惡意攻擊者往Web頁面里插入惡意腳本代碼,而程序對于用戶輸入內容未過濾,當用戶瀏覽該頁之時,嵌入其中Web里面的腳本代碼會被執(zhí)行,從而達到惡意攻擊用戶的特殊目的。
    2016-09-09
  • Java下SpringBoot創(chuàng)建定時任務詳解

    Java下SpringBoot創(chuàng)建定時任務詳解

    這篇文章主要介紹了Java下SpringBoot創(chuàng)建定時任務詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-07-07

最新評論

绿春县| 盐池县| 彩票| 上林县| 拉孜县| 白银市| 秦安县| 申扎县| 陇西县| 启东市| 满城县| 山西省| 盘山县| 娱乐| 朝阳市| 平罗县| 贵德县| 阿坝县| 苏尼特右旗| 湘乡市| 龙川县| 卓资县| 湾仔区| 沐川县| 峨山| 恩平市| 河西区| 南陵县| 师宗县| 阿拉善左旗| 万源市| 赤水市| 兰坪| 崇信县| 保山市| 襄汾县| 临桂县| 福鼎市| 连州市| 三亚市| 临漳县|