Is there a way to avoid magic strings with Spring @Qualifier annotation

Good evening.

Today I had my first Spring course.
My curiosity had me try things that wasn’t covered and I answered the main question I asked myself today. How do we handle multiple implementations of the same interface? This is done with different annotations:

  • @Primary tells which implementation is to be used by default.
  • @Resource belongs to javax.Annotations package but can be understood by Spring. The class to be used can be set through either its name or type attributes. The former takes a string which first character is lowercase. The latter takes a type and it is why I prefer this one.
@Resource(type = PersonV2.class)
    private IPerson person;
  • @Qualifier belongs to org.springframework.beans.factory.annotation package, so it is the “legit” annotation for such purpose. Unfortunately there is no overload allowing to pass a class I’d know of. It takes a string only.

So I had the idea to make it possible to pass the class name. There is an Introspector Type in java.beans package that does just that through its decapitalize() method.

I wrote a method around that:

public static String beanName(Class $class) {
   String simpleName = $class.getSimpleName();
   return Introspector.decapitalize(simpleName);

The problem is Qualifier does not only want a string, but also expects it to be a constant.

It tells otherwise :

Attribute value must be constant


The above code is pretty cool IMHO but it won’t work for the reason mentioned above (wants constant).

The code bellow won’t help neither.

public static final String PERSON_CLASS = ClassUtils.beanName(PersonV3.class);

I guess this has to do with compile time constant against runtime constant but I don’t know how to do such a thing.

Any suggestion?

Many thanks.