Is it possible to map Spring components through annotations using enums?
dependency-injection, enums, java, spring
Solution
is there a way I can specify my component's name by referring to the value in the enum?
No, there is not. If the annotation attribute was expecting an `enum`, you could just use the `enum`. But invoking a method does not resolve to a constant expression. You might think that you could make the field `public` and access it directly
@Named(MY_ENUMS.A.name)
but that won't work either because `MY_ENUMS.A.name` isn't a constant expression either.
The actual reason theat isn't a constant expression is that an enum constant is basically a variable. There is such a thing as a constant variable, which is a constant expression. For a variable to be a constant variable, it needs to be `final` and initialized with a constant expression. An `enum` constant is `final` but is not initialized with a constant expression. Basically an `enum` constant is compiled to
public static final YourEnum constant = new YourEnum();
The `new YourEnum()` expression is not a constant expression. And therefore the constant is not a constant variable and can't be used to resolve a `String` variable which it may be a constant variable.
Problem
I'm working with Spring 4, and I have an enum declared like... ``` public static enum MY_ENUMS { A(1, "enum1"), B(2, "enum2"); private final int key; private final String name; MY_ENUMS(int key, String name) { this.key = key; this.name = name; } public String getName() { return this.name; } public int getIndex() { return this.key; } } ``` Then, from my component I'm attempting to do something like... ``` // @Named is the equivalent of @Component for this use case // Making name public and trying this also does not work: // @Named(MY_ENUMS.A.name) @Named(MY_ENUMS.A.getName()) public class ServiceImplA implements IService { @Override public Object interfaceMethod() { // Some code specific to ServiceImplA here.... } } ``` This doesn't build and I know WHY this doesn't build. Basically, `MY_ENUMS.A.getName()` doesn't appear to the compilier as being constant, which would mean it cannot be used here. But the point of enums is that they allow you a method to declare constants in a useful way. So, with that being said, is there a way I can specify my component's name by referring to the value in the enum? I feel this should be possible given that enums are a special case/implementation of constant values but I can't think of a way to work around Spring (or maybe Java's) expectation that the value of the annotation be a straight up constant.