Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject the value of an enum into a property using spring

Tags:

java

spring

I have an enum similar to the below

public enum MyEnum {
ABC("some string"), 
DEF("some string"), 
GHI("another string");

String value;

private MyEnum(String value) {
    this.value = value;
}

public String value() {
    return this.value;
}}

And I would like to make a util:map using the value of the enum as the key not the enum itself. So the map would look like this:

"some string" -> "mapped output 1"
"another string" -> "mapped output 2"

I know I can use util:constant to get the enum but i need the value the enum represents.

So my config file at the minute looks like this:

<util:constant id="firstKey" static-field="package.MyEnum.ABC"/>
<util:constant id="secondKey" static-field="package.MyEnum.GHI" />


<util:map id="myMap">
    <entry key-ref="firstKey" value="mapped output 1" />
    <entry key-ref="secondKey" value="mapped output 2" /></util:map>

Is there a way I can get .value() or even get access to the value property to use it as the key?

I tried declaring the key type to be string in the hope spring would work it out but it seems to have just ignored this.

Using spring 2.5.1 and I cannot modify the enum

like image 886
James Avatar asked Dec 28 '12 16:12

James


1 Answers

If you don't have access to the expression language you'll have to fall back to an explicit MethodInvokingFactoryBean

<bean id="firstKey" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
  <property name="targetObject"><util:constant static-field="package.MyEnum.ABC"/></property>
  <property name="targetMethod" value="value" />
</bean>

You could shorten the repetitive XML a bit with an abstract parent bean definition.

<bean name="enumValue" abstract="true"
      class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
  <property name="targetMethod" value="value" />
</bean>

<bean id="firstKey" parent="enumValue">
  <property name="targetObject"><util:constant static-field="package.MyEnum.ABC"/></property>
</bean>

You could also skip the MethodInvokingFactoryBean and just use

<util:constant id="MyEnum_ABC" static-field="package.MyEnum.ABC" />
<bean id="firstKey" factory-bean="MyEnum_ABC" factory-method="value" />

but that means declaring separate top-level beans for each enum constant as well as for their value(), whereas using MIFB allows you to use anonymous inner beans.

like image 198
Ian Roberts Avatar answered Nov 14 '22 22:11

Ian Roberts