Skip to content

Revise RepeatableContainers API to better guide developers #34637

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
sbrannen opened this issue Mar 23, 2025 · 0 comments
Closed

Revise RepeatableContainers API to better guide developers #34637

sbrannen opened this issue Mar 23, 2025 · 0 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Milestone

Comments

@sbrannen
Copy link
Member

sbrannen commented Mar 23, 2025

Overview

Historically, the Spring Framework first had support for repeatable annotations based on convention and later added explicit support for Java 8's @Repeatable facility. Consequently, the support for both types of repeatable annotations has grown a bit intertwined over the years. However, modern Java applications typically make use of @Repeatable, and convention-based repeatable annotations have become more of a niche.

The RepeatableContainers API supports both types of repeatable annotations with @Repeatable support being the default. However, RepeatableContainers.of() makes it very easy to enable support for convention-based repeatable annotations while accidentally disabling support for @Repeatable, which can lead to subtle bugs – for example, if convention-based annotations are combined with @Repeatable annotations. In addition, it is not readily clear how one can combine @Repeatable support with convention-based repeatable annotations.

In light of the above, we have decided to revise the RepeatableContainers API to better guide developers to use @Repeatable support for almost all use cases while still supporting convention-based repeatable annotations for special use cases.

To achieve this, we will effectively rename RepeatableContainers.of() to RepeatableContainers.explicitRepeatable(), deprecating the former.

In addition, since the arguments supplied to RepeatableContainers.and() are in the reverse order of those supplied to all other repeatable annotation related methods (in RepeatableContainers, AnnotationUtils, and AnnotatedElementUtils), we will effectively rename add() to plus() and deprecate the former, and plus() will accept arguments in the same order as the rest of our repeated annotation APIs.

For example, instead of the following confusing mixture of repeatable/container and container/repeatable:

RepeatableContainers.of(A.class, A.Container.class).and(B.Container.class, B.class)

One will now be able to use:

RepeatableContainers.explicitRepeatable(A.class, A.Container.class).plus(B.class, B.Container.class)

We will also improve the documentation to point out that the following is the recommended approach to support convention-based repeatable annotations while retaining support for @Repeatable.

RepeatableContainers.standardRepeatables()
    .plus(MyRepeatable1.class, MyContainer1.class)
    .plus(MyRepeatable2.class, MyContainer2.class)

Related Issues

@sbrannen sbrannen added in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement labels Mar 23, 2025
@sbrannen sbrannen added this to the 7.0.0-M4 milestone Mar 23, 2025
@sbrannen sbrannen self-assigned this Mar 23, 2025
sbrannen added a commit to sbrannen/spring-framework that referenced this issue Mar 23, 2025
Historically, the Spring Framework first had support for repeatable
annotations based on convention and later added explicit support for
Java 8's @⁠Repeatable facility. Consequently, the support for both
types of repeatable annotations has grown a bit intertwined over the
years. However, modern Java applications typically make use of
@⁠Repeatable, and convention-based repeatable annotations have become
more of a niche.

The RepeatableContainers API supports both types of repeatable
annotations with @⁠Repeatable support being the default. However,
RepeatableContainers.of() makes it very easy to enable support for
convention-based repeatable annotations while accidentally disabling
support for @⁠Repeatable, which can lead to subtle bugs – for example,
if convention-based annotations are combined with @⁠Repeatable
annotations. In addition, it is not readily clear how to combine
@⁠Repeatable support with convention-based repeatable annotations.

In light of the above, this commit revises the RepeatableContainers API
to better guide developers to use @⁠Repeatable support for almost all
use cases while still supporting convention-based repeatable
annotations for special use cases.

Specifically:

- RepeatableContainers.of() is now deprecated in favor of the new
  RepeatableContainers.explicitRepeatable() method.

- RepeatableContainers.and() is now deprecated in favor of the new
  RepeatableContainers.plus() method which declares the repeatable and
  container arguments in the same order as the rest of Spring
  Framework's repeated annotation APIs.

For example, instead of the following confusing mixture of
repeatable/container and container/repeatable:

RepeatableContainers.of(A.class, A.Container.class)
    .and(B.Container.class, B.class)

Developers are now be able to use:

RepeatableContainers.explicitRepeatable(A.class, A.Container.class)
    .plus(B.class, B.Container.class)

This commit also overhauls the Javadoc for RepeatableContainers and
explicitly points out that the following is the recommended approach to
support convention-based repeatable annotations while retaining support
for @⁠Repeatable.

RepeatableContainers.standardRepeatables()
    .plus(MyRepeatable1.class, MyContainer1.class)
    .plus(MyRepeatable2.class, MyContainer2.class)

See spring-projectsgh-20279
Closes spring-projectsgh-34637
sbrannen added a commit to sbrannen/spring-framework that referenced this issue Mar 23, 2025
Historically, the Spring Framework first had support for repeatable
annotations based on convention and later added explicit support for
Java 8's @⁠Repeatable facility. Consequently, the support for both
types of repeatable annotations has grown a bit intertwined over the
years. However, modern Java applications typically make use of
@⁠Repeatable, and convention-based repeatable annotations have become
more of a niche.

The RepeatableContainers API supports both types of repeatable
annotations with @⁠Repeatable support being the default. However,
RepeatableContainers.of() makes it very easy to enable support for
convention-based repeatable annotations while accidentally disabling
support for @⁠Repeatable, which can lead to subtle bugs – for example,
if convention-based annotations are combined with @⁠Repeatable
annotations. In addition, it is not readily clear how to combine
@⁠Repeatable support with convention-based repeatable annotations.

In light of the above, this commit revises the RepeatableContainers API
to better guide developers to use @⁠Repeatable support for almost all
use cases while still supporting convention-based repeatable
annotations for special use cases.

Specifically:

- RepeatableContainers.of() is now deprecated in favor of the new
  RepeatableContainers.explicitRepeatable() method.

- RepeatableContainers.and() is now deprecated in favor of the new
  RepeatableContainers.plus() method which declares the repeatable and
  container arguments in the same order as the rest of Spring
  Framework's repeated annotation APIs.

For example, instead of the following confusing mixture of
repeatable/container and container/repeatable:

RepeatableContainers.of(A.class, A.Container.class)
    .and(B.Container.class, B.class)

Developers are now be able to use:

RepeatableContainers.explicitRepeatable(A.class, A.Container.class)
    .plus(B.class, B.Container.class)

This commit also overhauls the Javadoc for RepeatableContainers and
explicitly points out that the following is the recommended approach to
support convention-based repeatable annotations while retaining support
for @⁠Repeatable.

RepeatableContainers.standardRepeatables()
    .plus(MyRepeatable1.class, MyContainer1.class)
    .plus(MyRepeatable2.class, MyContainer2.class)

See spring-projectsgh-20279
Closes spring-projectsgh-34637
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

1 participant