DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Filtering Java Collections via Annotation-Driven Introspection
  • Mastering Spring: Synchronizing @Transactional and @Async Annotations With Various Propagation Strategies
  • Java, Spring Boot, and MongoDB: Performance Analysis and Improvements
  • Smart Dependency Injection With Spring: Assignability (Part 2 of 3)

Trending

  • 5 Mistakes Companies Make When Working With Staff Engineers
  • How to Evaluate Coding Agents With Harbor Framework, Python, Docker
  • Full-Text Search Meets the Graph: Apache Lucene Inside Neo4j
  • Chaos Engineering and Kafka In Action: Topic Level Idempotence and Retry Check

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Coding
  3. Java
  4. Composing Custom Annotations in Spring

Composing Custom Annotations in Spring

Spring, building custom composite annotations with @AliasFor. The mechanism allows developers to create custom composite annotations.

By 
Andrei Tuchin
DZone Core CORE ·
Dec. 24, 23 · Tutorial
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
11.3K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

Spring, a widely embraced Java framework, empowers developers with a versatile toolkit to build robust and scalable applications. Among its many features, custom annotations are a powerful mechanism for enhancing code readability, reducing boilerplate, and encapsulating complex configurations. This article will explore the art of composing custom annotations in Spring, unraveling their potential through practical examples.

The Essence of Custom Annotations

Annotations in Java serve as a form of metadata, offering a way to add supplementary information to code elements. While Spring provides an array of built-in annotations, creating custom annotations allows developers to tailor their applications precisely to their needs.

Custom annotations in Spring find applications in various scenarios:

  • Configuration Simplification: Abstracting common configurations into custom annotations reduces the clutter in code and configuration files, leading to a more maintainable codebase.
  • Readability and Organization: Annotations offer a concise and expressive means to convey the intent and purpose of classes, methods, or fields, enhancing overall code organization and readability.
  • Behavioral Constraints: Custom annotations can be employed to enforce constraints on the usage of components, ensuring adherence to specific patterns or sequences.

Set-Up

All examples are built for Swagger, with the usage of Swagger annotations, but all below may be extended to your case. 

Set up Swagger:

Java
 
<dependency>
	<groupId>io.springfox</groupId>
	<artifactId>springfox-swagger2</artifactId>
	<version>3.0.0</version>
</dependency>


Anatomy of a Custom Annotation

Creating a custom annotation in Spring involves defining a new interface annotated with @interface

Let's embark on the journey of crafting a straightforward custom annotation called @AuthExample

Java
 
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@ApiResponses(value = {
        @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content),
        @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content),
        @ApiResponse(responseCode = "200")})
public @interface AuthExample {
}


After applying the annotation @AuthExample all annotations in composition are applied. In this example, @Target specifies that the annotation can be applied only to methods, and @Retention ensures that the annotation information is available at runtime. 

How To Pass Attributes Into Custom Annotations

One powerful feature that Spring provides is the ability to create custom composite annotations using @AliasFor. The @AliasFor annotation is part of the Spring framework and is used to declare an alias for an attribute within the same annotation type. This allows developers to create composite annotations by reusing attributes from other annotations, promoting code reuse and enhancing clarity. In this example, the @AuthExample annotation is composed using @AliasFor to alias the myDescription attribute to the description attribute of Operation

Java
 
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@ApiResponses(value = {
        @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content),
        @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content),
        @ApiResponse(responseCode = "200")})
@Operation
public @interface AuthExample {
    @AliasFor(annotation = Operation.class, attribute = "description")
    String myDescription() default "";
}


Now, applying @AuthExample(myDescription = "Very smart solution") is the same as applying @Operation(myDescription = "Very smart solution")with all annotations included.

There is a way to run multi-level @AliasFor 

Java
 
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Operation
public @interface Level1 {
    @AliasFor(annotation = Operation.class, attribute = "description")
    String description();
}

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Level1(description = "That description is ignored")
@interface Level2 {
    @AliasFor(annotation = Level1.class, attribute = "description")
    String description() default "Level2 default description";
}

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Level2
@interface Level3 {
    @AliasFor(annotation = Level2.class, attribute = "description")
    String description() default "Level3 default description";
}


In the example above, the value of default is associated with the annotation applied in the code.

Resolving Attribute Values With @AliasFor

When using @AliasFor, it's important to understand how attribute values are resolved. The value specified in the annotated element takes precedence, and if not provided, the value from the aliased attribute is used. This ensures flexibility and allows developers to customize behavior as needed.

Conclusion

Custom annotations in Spring elevate the expressiveness and flexibility of your codebase. By crafting annotations like @AuthExample, developers can encapsulate retry logic and reduce the complexity of error handling. Also, creating with @AliasFor in Spring provides a powerful way to simplify configuration and promote code reuse.  As you delve deeper into Spring's annotation-driven world, custom annotations will become indispensable tools in your toolkit, offering a scalable and elegant approach to building resilient and well-organized applications.

Annotation Spring Framework Attribute (computing) Java (programming language) authentication

Opinions expressed by DZone contributors are their own.

Related

  • Filtering Java Collections via Annotation-Driven Introspection
  • Mastering Spring: Synchronizing @Transactional and @Async Annotations With Various Propagation Strategies
  • Java, Spring Boot, and MongoDB: Performance Analysis and Improvements
  • Smart Dependency Injection With Spring: Assignability (Part 2 of 3)

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook