深入淺出SpringBootInAction

一、簡介

Spring是一個開源框架,可以使開發者構建企業級應用。它提供了Java開發人員豐富的企業級功能,同時可以快速簡單的進行開發。SpringBoot是Spring家族中的一員,它是一個微框架,能夠用最少的配置使開發者快速地搭建一個基於Spring的企業級應用。SpringBootInAction這本書從深入淺出、實戰為驅動的角度出發,全面講解了SpringBoot的使用方法和開發技巧。本篇文章將從多個方面對SpringBootInAction進行詳細的闡述。

二、快速入門

在使用SpringBoot進行應用開發之前,需要了解SpringBoot應用的基本結構以及如何進行快速配置。SpringBoot應用的基本結構如下:

AppName/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com.example/
│   │   │       └── DemoApplication.java
│   │   └── resources/
│   │       ├── application.properties
│   │       └── templates/
│   └── test/
│       └── java/
│           └── com.example/
│               └── DemoApplicationTests.java
└── pom.xml

其中,DemoApplication是SpringBoot應用的啟動器。application.properties是SpringBoot應用的配置文件。在配置文件中,進行一些啟動時需要加載的配置,比如設置端口號,設置數據庫url等。pom.xml是SpringBoot應用的依賴管理文件。在這裡可以管理應用程序需要的所有依賴項。SpringBoot應用支持多種開發方式,採用使用內置的Tomcat服務器進行開發的方式。同樣,Spring Boot也支持使用外部的Tomcat或者Jetty等服務器運行應用程序。

三、自定義註解

在應用程序的開發過程中,經常會使用到自定義註解。SpringBoot通過註解可以方便地實現各種各樣的功能。下面我們來看一個自定義註解的示例代碼:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnnotation {
    String value();
}

在這段代碼中,@Retention和@Target是Java的元註解,用於定義註解類型和註解作用域。MyAnnotation是定義的註解名。這個註解表示給該註解添加一個value屬性,該屬性是一個字符串類型。在使用自定義註解時,只需要在需要使用的地方打上@MyAnnotation註解,並設置value屬性值即可。

四、日誌

在程序開發過程中,日誌模塊是非常必要的。SpringBoot內置了Logback、Log4j2、各類java.util.logging和 Java/SLF4J等多種日誌框架,我們可以根據自己的需要進行選擇。下面給出一個使用Logback作為日誌框架的示例代碼:

@Slf4j
@Component
public class LogComponent {
    public void debug() {
        log.debug("this is debug level!");
    }
    public void error() {
        log.error("this is error level!");
    }
    public void info() {
        log.info("this is info level!");
    }
    public void warn() {
        log.warn("this is warn level!");
    }
}

在這段代碼中,@Slf4j註解是Lombok庫提供的一個註解,它自動為這個類添加一個log日誌對象。在方法中通過log.debug()方法輸出調試信息、log.error()方法輸出錯誤信息、log.info()方法輸出普通信息、log.warn()方法輸出警告信息。

五、數據庫操作

在SpringBoot中,使用JPA能夠方便地進行數據庫操作。下面給出一個使用JPA操作MySQL數據庫的示例代碼:

@Repository
public interface UserRepository extends JpaRepository {
    User findByUsername(String username);
    Page findAll(Pageable pageable);
}
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserRepository userRepository;
    @Override
    public User findByUsername(String username) {
        return userRepository.findByUsername(username);
    }
    @Override
    public Page findAll(Pageable pageable) {
        return userRepository.findAll(pageable);
    }
}

在這段代碼中,User是一個實體類,表示數據庫中的一張用戶表。UserRepository是一個接口,繼承自JpaRepository,這個接口提供的方法可以使我們方便地進行數據庫操作。UserServiceImpl是實現UserService接口的實現類。在實現類中,可以通過@Autowired註解將UserRepository對象自動注入到當前類中。在需要進行數據庫操作時,可以通過調用UserRepository的方法,完成數據庫操作。

六、限流

在某些場景下,我們需要進行限流。常見的限流方式有TOKEN桶、漏斗算法等。下面給出一個使用基於註解的Redis限流示例代碼:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RateLimiter {
    String key();
    int rate();
    int capacity();
}
@Component
public class RedisRateLimiter {
    @Autowired
    private RedisTemplate redisTemplate;
    public Mono<Void> isAllowed(String key, int rate, int capacity) {
        return redisTemplate.execute(RedisScript.of(getLuaScript()), 
            RedisSerializer.string(), RedisSerializer.string(), 
            Collections.singletonList(key), 
            rate + "", capacity + "", System.currentTimeMillis() + "")
            .filter(result -> Long.parseLong(result.toString()) != 0);
    }
    private String getLuaScript() {
        return "local key = KEYS[1]\n" +
               "local rate = tonumber(ARGV[1])\n" +
               "local capacity = tonumber(ARGV[2])\n" +
               "local nowMicros = tonumber(ARGV[3])\n" +
               "local fillTime = capacity / rate * 1000000\n" +
               "local lastPermitTime = redis.call('HGET', key, 'lastPermitTime')\n" +
               "local permits = tonumber(redis.call('HGET', key, 'permits'))\n" +
               "if (not lastPermitTime) then\n" +
               "    redis.call('HSET', key, 'lastPermitTime', nowMicros)\n" +
               "    redis.call('HSET', key, 'permits', 1)\n" +
               "    redis.call('PEXPIRE', key, math.ceil(fillTime / 1000) + 1)\n" +
               "    return 1\n" +
               "else\n" +
               "    local nextPermitTime = tonumber(lastPermitTime) + fillTime\n" +
               "    local freshPermits = math.floor((nowMicros - tonumber(lastPermitTime)) / fillTime)\n" +
               "    if (freshPermits > 0) then\n" +
               "        redis.call('HSET', key, 'permits', math.min(freshPermits + permits, capacity))\n" +
               "        redis.call('HSET', key, 'lastPermitTime', lastPermitTime + freshPermits * fillTime)\n" +
               "    end\n" +
               "    if (nextPermitTime < nowMicros) then\n" +
               "        redis.call('HSET', key, 'permits', math.min(1, capacity))\n" +
               "        redis.call('HSET', key, 'lastPermitTime', nowMicros)\n" +
               "        return 1\n" +
               "    else\n" +
               "        return 0\n" +
               "    end\n" +
               "end";
    }
}
@RestController
public class DemoController {
    @Autowired
    private RedisRateLimiter redisRateLimiter;
    @RateLimiter(key = "test", rate = 100, capacity = 1000)
    @GetMapping("/")
    public String hello() {
        Mono mono = redisRateLimiter.isAllowed("test", 100, 1000);
        mono.subscribe();
        return "hello";
    }
}

在這段代碼中,RateLimiter是一個自定義註解,用於設置Redis限流相關參數。RedisRateLimiter是一個Redis限流器,使用RedisTemplate實現了對Redis的訪問。DemoController是一個RestController,通過@GetMapping註解配置了一個路由,同時通過@RateLimiter註解配置了一些限流參數。接下來,當有請求來到時,會進入RedisRateLimiter中進行參數判定,達到限流效果。

七、總結

本篇文章對SpringBootInAction這本書進行了詳細的講解。通過多個方面的實例,深入闡述了SpringBoot應用的開發技巧和使用方法。在實際應用中,各個方面都需要考慮到。只有熟悉和掌握了這些技術,才能更好地使用SpringBoot進行開發。讓我們共同進步,寫出更好的代碼!

原創文章,作者:SPFEC,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/332110.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
SPFEC的頭像SPFEC
上一篇 2025-01-21 17:29
下一篇 2025-01-21 17:30

相關推薦

  • 深入淺出統計學

    統計學是一門關於收集、分析、解釋和呈現數據的學科。它在各行各業都有廣泛應用,包括社會科學、醫學、自然科學、商業、經濟學、政治學等等。深入淺出統計學是指想要學習統計學的人能夠理解統計…

    編程 2025-04-25
  • 深入淺出torch.autograd

    一、介紹autograd torch.autograd 模塊是 PyTorch 中的自動微分引擎。它支持任意數量的計算圖,可以自動執行前向傳遞、後向傳遞和計算梯度,同時提供很多有用…

    編程 2025-04-24
  • 深入淺出SQL佔位符

    一、什麼是SQL佔位符 SQL佔位符是一種佔用SQL語句中某些值的標記或佔位符。當執行SQL時,將使用該標記替換為實際的值,並將這些值傳遞給查詢。SQL佔位符使查詢更加安全,防止S…

    編程 2025-04-24
  • 深入淺出:理解nginx unknown directive

    一、概述 nginx是目前使用非常廣泛的Web服務器之一,它可以運行在Linux、Windows等不同的操作系統平台上,支持高並發、高擴展性等特性。然而,在使用nginx時,有時候…

    編程 2025-04-24
  • 深入淺出ThinkPHP框架

    一、簡介 ThinkPHP是一款開源的PHP框架,它遵循Apache2開源協議發布。ThinkPHP具有快速的開發速度、簡便的使用方式、良好的擴展性和豐富的功能特性。它的核心思想是…

    編程 2025-04-24
  • 深入淺出arthas火焰圖

    arthas是一個非常方便的Java診斷工具,包括很多功能,例如JVM診斷、應用診斷、Spring應用診斷等。arthas使診斷問題變得更加容易和準確,因此被廣泛地使用。artha…

    編程 2025-04-24
  • 深入淺出AWK -v參數

    一、功能介紹 AWK是一種強大的文本處理工具,它可以用於數據分析、報告生成、日誌分析等多個領域。其中,-v參數是AWK中一個非常有用的參數,它用於定義一個變量並賦值。下面讓我們詳細…

    編程 2025-04-24
  • 深入淺出Markdown文字顏色

    一、Markdown文字顏色的背景 Markdown是一種輕量級標記語言,由於其簡單易學、易讀易寫,被廣泛應用於博客、文檔、代碼注釋等場景。Markdown支持使用HTML標籤,因…

    編程 2025-04-23
  • 深入淺出runafter——異步任務調度器的實現

    一、runafter是什麼? runafter是一個基於JavaScript實現的異步任務調度器,可以幫助開發人員高效地管理異步任務。利用runafter,開發人員可以輕鬆地定義和…

    編程 2025-04-23
  • 深入淺出TermQuery

    一、TermQuery概述 TermQuery是Lucene中最基本、最簡單、最常見的查詢方法之一。它完全符合其名字,意味着只能對一個單詞進行查詢。 TermQuery可以用於搜索…

    編程 2025-04-23

發表回復

登錄後才能評論