Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Introduce predicate for searching enclosing classes in MergedAnnotations #28207

Closed
sbrannen opened this issue Mar 21, 2022 · 1 comment
Closed
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 21, 2022

Overview

Due to the deprecation of SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES (see #28079), we will introduce a way for users to provide a Predicate<Class<?>> that is used to decide when the enclosing class for the class supplied to the predicate should be searched.

This will give the user complete control over the "enclosing classes" aspect of the search algorithm in MergedAnnotations.

  • To achieve the same behavior as TYPE_HIERARCHY_AND_ENCLOSING_CLASSES, a user can provide clazz -> true as the predicate.
  • To limit the enclosing class search to inner classes, a user can provide ClassUtils::isInnerClass as the predicate.
  • To limit the enclosing class search to static nested classes, a user can provide ClassUtils::isStaticClass as the predicate.
  • For any other use case (such as in TestContextAnnotationUtils in spring-test), the user can provide a custom predicate.

Proposal

Based on the outcome of #28208, a searchEnclosingClass predicate could be supplied when using the TYPE_HIERARCHY search strategy as follows.

MergedAnnotations annotations = MergedAnnotations
    .search(SearchStrategy.TYPE_HIERARCHY)
    .withEnclosingClasses(ClassUtils::isInnerClass)
    .from(myClass);

By limiting when a searchEnclosingClass predicate can be supplied in the fluent search API, we can prevent users from trying to supply such a predicate for other SearchStrategy types.

@sbrannen sbrannen added in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement labels Mar 21, 2022
@sbrannen sbrannen added this to the 6.0.0-M4 milestone Mar 21, 2022
@sbrannen sbrannen self-assigned this Mar 21, 2022
@sbrannen
Copy link
Member Author

Blocked until #28208 is implemented

@sbrannen sbrannen added the status: blocked An issue that's blocked on an external project change label Mar 21, 2022
sbrannen added a commit to sbrannen/spring-framework that referenced this issue Mar 22, 2022
The impetus for this is to be able to use ClassUtils::isStaticClass
or the existing ClassUtils::isInnerClass as a method reference for
class-based predicates that need to differentiate between static
nested types and inner classes.

See spring-projectsgh-28207
sbrannen added a commit that referenced this issue Mar 22, 2022
Prior to this commit, searching for merged annotations on an
AnnotatedElement in the MergedAnnotations model was only supported via
various overloaded from(...) factory methods. In addition, it was not
possible to provide a custom AnnotationFilter without providing an
instance of RepeatableContainers.

This commit introduces a fluent API for searches in MergedAnnotations
to address these issues and improve the programming model for users of
MergedAnnotations.

To begin a search, invoke MergedAnnotations.search(SearchStrategy) with
the desired search strategy. Optional configuration can then be
provided via one of the with(...) methods. To perform a search, invoke
from(AnnotatedElement), supplying the element from which to begin the
search -- for example, a Class or a Method.

For example, the following performs a search on MyClass within the
entire type hierarchy of that class while ignoring repeatable
annotations.

MergedAnnotations mergedAnnotations =
    MergedAnnotations.search(SearchStrategy.TYPE_HIERARCHY)
        .withRepeatableContainers(RepeatableContainers.none())
        .from(MyClass.class);

To reuse search configuration to perform the same type of search on
multiple elements, you can save the Search instance as demonstrated in
the following example.

Search search = MergedAnnotations.search(SearchStrategy.TYPE_HIERARCHY)
                    .withRepeatableContainers(RepeatableContainers.none());

MergedAnnotations mergedAnnotations = search.from(MyClass.class);
// do something with the MergedAnnotations for MyClass
mergedAnnotations = search.from(AnotherClass.class);
// do something with the MergedAnnotations for AnotherClass

In addition, this fluent search API paves the way for introducing
support for a predicate that controls the search on enclosing classes
(gh-28207) and subsequently for completely removing the
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search strategy (gh-28080).

Closes gh-28208
@sbrannen sbrannen removed the status: blocked An issue that's blocked on an external project change label Mar 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in 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