Spring Boot でカスタム アノテーションを作成するための究極ガイド

PHPz
リリース: 2024-08-25 18:01:02
オリジナル
411 人が閲覧しました

The Ultimate Guide to Create Custom Annotations in Spring Boot
このようなアノテーションは、Spring Boot のプロジェクト全体に埋め込まれます。

しかし、これらの注釈がどのような問題を解決するか知っていますか?

そもそもなぜカスタムアノテーションが導入されたのでしょうか?

カスタム注釈を作成するには?

今日は以下について取り上げます:

  • カスタム注釈を作成する理由?
  • これらの注釈を使用する主な利点は何ですか?
  • カスタム注釈を作成するには?
  • アノテーション付きメソッドはどのように呼び出されますか?
  • カスタム注釈をいつ使用するか?
  • カスタム注釈を使用してはいけない場合は?
  • カスタム注釈を使用するデメリットは何ですか?

?カスタム注釈を作成する理由

Spring Boot では、アノテーションはメタデータを追加する単なる手段ではありません。彼ら

  • 複雑なタスクを簡素化する
  • 定型コードを削減
  • コードの可読性を向上させる

Spring がカスタム アノテーションを導入する前は、開発者は XML 構成ファイルを使用して電子メール検証などの構成を管理する必要がありました。

XML 構成は、電子メール アドレスの検証などのタスクを実行するために Bean、バリデーター、およびその他の必要なコンポーネントを定義します。

Spring アプリケーションで XML を使用して電子メール検証を構成する方法の例を次に示します。

The Ultimate Guide to Create Custom Annotations in Spring Bootご覧のとおり、これは何百ものクラスが存在し、その多くが相互に依存する悪夢になる可能性があります。

また、開発者は新しい依存関係を追加する必要があるたびにこの XML を調べなければならないことも意味しました。

カスタム注釈の主な利点

構成の簡素化

Spring では、開発者がコード内で直接アノテーションを使用できるようにすることで構成を簡素化するカスタム アノテーションが導入されました。

これにより、広範な XML 設定の必要性が減り、コードベースがクリーンになり、保守が容易になりました。

宣言型プログラミングのサポート

Spring のカスタム アノテーションにより、宣言的なアプローチが可能になります。

開発者は、@Transactional、@Cacheable、@Scheduled などのアノテーションを使用して、基礎となるロジックを記述することなく、必要な動作を宣言できます。

これにより、コードがより読みやすく保守しやすくなります。

横断的な懸念事項への対応

Spring のカスタム アノテーションは、アスペクト指向プログラミング (AOP) でよく使用され、開発者が横断的な問題を一元的に処理できるようにします。

たとえば、 @Transactional アノテーションは、コード全体にトランザクション管理ロジックを分散させることなく、複数のメソッドまたはクラスにわたるトランザクションを管理します。

定型コードの削減

一般的な動作をカプセル化することで定型コードの必要性を減らします。

たとえば、@Autowired アノテーションは依存関係の注入を簡素化し、明示的なコンストラクターやセッター メソッドを必要とするのではなく、Spring が自動的に依存関係を注入できるようにします

@Autowired を使用する必要があるかどうかは別の議論です。

コードの読みやすさと一貫性の向上

設定と横断的な関心事を注釈に抽象化することで、Spring はコードの可読性を向上させます。

あなたと同僚の開発者は、そのアノテーションを確認することでメソッドやクラスの目的をすぐに理解でき、アノテーションはコードベース全体で一貫性を保つのに役立ちます。

フレームワークの柔軟性と拡張性

カスタム アノテーションを使用すると、開発者は特定のニーズに合わせてアノテーションを作成できるため、標準化された方法でフレームワークの機能を拡張できます。

この柔軟性により、Spring は複数のアプリケーションやアーキテクチャにわたって関連性があり、強力であり続けることができます。

?カスタム注釈を作成する方法

ステップ 1: 注釈を定義する

インターフェースを定義して新しいアノテーションを作成します。

@interface を使用して宣言します。

    メタアノテーションを追加して、アノテーションがどのように動作するかを指定します。
  • リーリー
  • @Target: アノテーションを使用できる場所 (メソッド、クラスなど) を示します。
  • @Retention: アノテーションが保持される期間 (実行時、コンパイル時など) を示します。
  • ステップ 2: 注釈を処理するアスペクトを作成する
  • Spring の BeanPostProcessor、Aspect、またはカスタム アノテーション処理ロジックを使用して、アノテーションを処理するカスタム ロジックを作成できます。
リーリー

ステップ 3: 注釈を適用する

定義に従ってカスタム アノテーションをメソッド、フィールド、またはクラスに適用します。

package co.officegeek.tokenratelimiter; import org.springframework.stereotype.Service; @Service public class TestService { @LogExecutionTime public void serve() throws InterruptedException { // Simulate some work Thread.sleep(2000); } }
ログイン後にコピー

How It Works:

  • The @LogExecutionTime annotation doesn't cause any method to be called directly.
  • The Spring AOP framework detects that a method has the @LogExecutionTime annotation using reflection.
  • The LogExecutionTimeAspect aspect is configured to apply around advice when a method with the @LogExecutionTime annotation is called.
  • The logExecutionTime method in the aspect is executed before and after the annotated method (serve), logging the execution time.

The Ultimate Guide to Create Custom Annotations in Spring Boot


How does the annotated method get invoked?

When you apply a custom annotation to a method, class, or field, the annotation itself doesn't directly cause any method to be called.

Instead, the logic associated with the annotation is typically implemented using reflection or aspect-oriented programming (AOP) in frameworks like Spring.

Here's a breakdown of how the compiler and runtime environment know what method to call when an annotation is applied:

1. Compile-Time Processing (Annotation Processors)

Some annotations are handled at compile time by annotation processors.

Java's javax.annotation.processing package allows developers to create custom annotation processors that generate code, validate annotations, or even modify the abstract syntax tree (AST) of the code being compiled.

The annotation processor reads the annotations during compilation and executes code based on those annotations.

This can include generating new classes or methods that the code will use later.

The @Override annotation is a compile-time annotation that doesn't invoke a method but instead tells the compiler to check if the method actually overrides a superclass method.

How It Works:

  • You define a custom annotation processor by extending AbstractProcessor and overriding the process method.
  • The processor will be invoked by the compiler when it encounters your annotation, allowing you to generate code or perform other tasks.

2. Runtime Processing (Reflection)

Custom annotations can be processed at runtime using reflection.

The runtime system (e.g., a framework like Spring) uses reflection to detect the presence of annotations on methods, classes, or fields, and then applies the corresponding behavior.

A custom annotation like @LogExecutionTime doesn't directly trigger any method call.

Instead, an aspect or some other reflective mechanism checks for the presence of the annotation at runtime and then wraps the method call with additional logic.

How It Works:

  • At runtime, you use Java's reflection API to check if a method or class has a specific annotation using methods like isAnnotationPresent.
  • Once detected, you can invoke methods or execute logic associated with that annotation. For example, if a method has a @LogExecutionTime annotation, you might measure the time before and after the method call.

3. Aspect-Oriented Programming (AOP)

In frameworks like Spring, AOP is commonly used to handle custom annotations.

AOP allows you to define "aspects" that can intercept method calls and perform additional processing before or after the method execution.

When the AOP framework (e.g. Spring AOP) detects an annotation, it triggers the execution of an advice method associated with the aspect.

This advice method contains the logic that the AOP framework executes when the annotated method is called.

A @Transactional annotation in Spring doesn't execute any logic by itself.

Instead, the Spring framework's AOP infrastructure intercepts calls to methods annotated with @Transactional and wraps them with transaction management logic.

How It Works:

  • You define an aspect class with advice methods that are associated with specific pointcuts (join points where you want to apply the advice).
  • The aspect uses annotations like @Around or @Before to specify when the advice should be executed.
  • The AOP framework ensures that when a method with a custom annotation is called, the corresponding advice is executed automatically.

Use Cases Where Custom Annotations Are a Good Approach

Cross-Cutting Concerns

Custom annotations are ideal for handling cross-cutting concerns like logging, security, transaction management, and caching.

These are concerns that affect multiple parts of an application but are not related to the core business logic.

上面的 @LogExecutionTime 註解就是一個很好的例子,因為它可以在所有方法中使用,而且它沒有任何業務邏輯。

聲明式程式設計

當您想要指定應該發生什麼而不是如何發生時,自訂註解提供了一種乾淨且富有表現力的方式來執行此操作。

@Cacheable 或 @Retry 等註解允許開發人員以聲明方式啟用快取或重試邏輯,而無需手動編寫實作程式碼。

框架或庫集成

自訂註解可以透過隱藏易於使用的註解背後的複雜性來簡化框架或程式庫的整合。

Spring 中的 @Autowired 這樣的註解有助於注入依賴項,而無需手動實例化它們。

複雜邏輯的封裝

當複雜的邏輯需要以可重複使用的方式封裝時,自訂註解可以提供一個乾淨的 API 來應用此邏輯。

像@RateLimit這樣的註解可以封裝邏輯來限制方法被呼叫的次數,而不會用這個邏輯來擾亂方法的主體。

不應使用自訂註解的用例

簡單或一次性的邏輯

如果邏輯很簡單或只需要在一個地方應用,那麼創建自訂註解就太過分了,並且會使程式碼不必要地複雜化。

需要動態行為的邏輯

註解是在編譯時靜態定義的,不適合需要在執行時動態決定行為的場景。

如果方法的行為應根據使用者輸入或外部配置而改變,則使用自訂註解處理此問題可能會導致複雜的解決方案。

業務邏輯

核心業務邏輯不應該被抽象化為自訂註釋,因為這會使邏輯不那麼透明且難以維護。

使用@ProcessOrder這樣的註解來封裝業務流程可能會隱藏重要的業務規則,使程式碼更難理解和維護。

註解之間複雜的交互

如果行為依賴多個註釋之間的複雜交互,則可能會導致意外結果並使程式碼難以理解和調試。

組合影響相同方法的多個自訂註解(例如@Retry、@Cacheable、@LogExecutionTime)可能會導致不可預測的行為並且難以管理

效能關鍵程式碼

自訂註解通常依賴反射或代理機制,這會帶來效能開銷。

它們不應該用在程式碼的效能關鍵部分。

使用自訂註解向在緊密循環中呼叫數百萬次的方法添加日誌記錄可能會顯著降低效能。

?摘要 - 何時使用自訂註釋

自訂註解非常適合處理橫切問題,例如日誌記錄、安全性和事務管理。

它們也非常適合您需要在應用程式的多個部分應用相同行為的場景。

但是,對於簡單、一次性的邏輯,或需要細粒度控制和靈活性的情況,自訂註解可能不是最好的方法。

在決定實施之前請考慮權衡。

?最後的想法

自訂註解是 Spring Boot 武器庫中的強大工具,但像任何工具一樣,應該謹慎使用它們。

它們提供了一種乾淨、可重用的方式來處理重複性任務並在程式碼庫中強制執行一致性。

但請注意潛在的缺點,尤其是複雜性和性能方面。


??公告

我正在為軟體開發人員和有抱負的微服務架構師推出為期 10 天的隊列課程,介紹如何使用 Spring Boot 和 Bucket4j 設計和實現速率限制服務。

您將學到:

✅ 如何設計與建造可投入生產的微服務

✅ 深入了解速率限制演算法及其實現

✅ Spring Boot 開發、測試和容器化的最佳實踐

但這也是關於

✅ 將項目分解為具體任務

✅ 對自己負責

✅ 正確設計與建造專案

它針對的是想要設計和開發微服務的軟體開發人員,這是與大多數公司相關的用例。

特別適合那些處於軟體開發人員職業生涯早期的人,他們可能沒有“專案經驗”,但有大量的熱情和雄心。

如果您認為這對您有幫助,或者即使您只是想了解更多:

登記您的興趣,我會讓您知道研討會詳情。


這首先發佈在我的子堆疊上。訂閱我的 Substack - Weekend Developer 以第一時間獲取更新。

您是需要對您所寫的程式碼提供回饋的開發人員嗎?

或您是否希望有人審查您的程式碼以便您做正確的事情?

我幫助人們進行免費的程式碼審查會議,以便他們能夠儘早獲得回饋並編寫更好的程式碼

在 Twitter (X) 或 LinkedIn 上私訊我,我將協助您編寫程式碼。

以上がSpring Boot でカスタム アノテーションを作成するための究極ガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!