Skip to content

Provide programmatical means to get beans of type in order #24882

Closed
@jxblum

Description

@jxblum

Currently, the Spring Framework API (e.g. ListableBeanFactory) provides no programmatic means to acquire beans in order.

It is possible, however, to acquire beans in order, for beans in/directly annotated with the @Order annotation or beans in/directly implementing the Ordered interface, using dependency injection (DI) with the @Autowired or @Resource annotations.

For example, given the following bean classes...

class SomeBean { ... }

class X extends SomeBean implements Ordered {

  @Override
  public int getOrder() {
    return -1;
}

@Order(-2)
class Y extends SomeBean { }

class Z extends ZeroOrderedBean { }

@Order(0)
abstract class ZeroOrderedBean extends SomeBean { }

And configuration...

@Configuration
class MyConfiguration {

  @Bean("A")
  @Order(3)
  SomeBean a() {
    return  new SomeBean();
  }

  @Bean("B")
  @Order(1)
  SomeBean b() {
    return new SomeBean();
  }

  @Bean("C")
  @Order(2)
  SomeBean c() {
    return new SomeBean();
  }

  @Bean("D")
  @Order(4)
  SomeBean d() {
    return new SomeBean();
  }

  @Bean("U")
  SomeBean unorderedBean() {
    return new SomeBean();
  }

  @Bean("X")
  X x() {
    return new X();
  }

  @Bean("Y")
  Y y() {
    return new Y();
  }

  @Bean("Z")
  Z z() {
    return new Z();
  }
}

Then, an application component can inject an array or List of SomeBean in order, like so...

@Component
class MyApplicationComponent {

  @Autowired
  SomeBean[] someBeans;

  ...
}

All SomeBean objects will be added to the array in the following order: Y, X, Z, B, C, A, D, U. This is aptly documented and described in the Order annotation Javadoc.

However, as a developer, if I wanted to acquire the beans using some programmatic means in the same order, this is not possible via the API (e.g. such as ListableBeanFactory.getBeansOfType(..)), AFAIK.

ListableBeanFactory.getBeansOfType(..) returns beans in bean definition declaration order as far as possible, as described in the Javadoc. However, this is not exactly the outcome I was looking to achieve in my particular case.

There are a few utility classes, such as BeanFactoryUtils and BeanFactoryAnnotationUtils containing a few extended container functions. However, none contain a function quite like I describe here.

The AutowireCapableBeanFactory.resolveDependency(..) container method handles dependency injection points, but is not exactly the API I am looking to call. Rather, I prefer something more like getBeansOfType(..).

To better demonstrate what I am asking for, I have built a utility class method in SDG to perform the desired function. This can be seen in the SpringUtils.getBeansOfTypeOrdered(..) method along with the associated helper methods.

I have also written a test to demonstrate and assert the desired behavior.

If this function would be useful in the core Spring Framework, as part of a utility class or something, please consider. If not, feel free to ignore and close this ticket.

Thank you for your consideration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: invalidAn issue that we don't feel is valid

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions