Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to map Spring components through annotations using enums?

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.

like image 949
Dave Avatar asked Apr 22 '14 23:04

Dave


1 Answers

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.

like image 151
Sotirios Delimanolis Avatar answered Oct 31 '22 14:10

Sotirios Delimanolis