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 itsname
ortype
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
@Qualifier(ClassUtils.beanName(PersonV3.class))
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);
//...
@Qualifier(PERSON_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.